lkml.org 
[lkml]   [2011]   [Jul]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 10/14] net/core/scm.c: target capable() calls to user_ns owning the net_ns
    Date
    From: Serge E. Hallyn <serge.hallyn@canonical.com>

    The uid/gid comparisons don't have to be pulled out. This just seemed
    more easily proved correct.

    Signed-off-by: Serge E. Hallyn <serge.hallyn@canonical.com>
    Cc: Eric W. Biederman <ebiederm@xmission.com>
    ---
    net/core/scm.c | 41 ++++++++++++++++++++++++++++++++++-------
    1 files changed, 34 insertions(+), 7 deletions(-)
    diff --git a/net/core/scm.c b/net/core/scm.c
    index 4c1ef02..21b5d0b 100644
    --- a/net/core/scm.c
    +++ b/net/core/scm.c
    @@ -43,17 +43,44 @@
    * setu(g)id.
    */

    -static __inline__ int scm_check_creds(struct ucred *creds)
    +static __inline__ bool uidequiv(struct cred *src, struct ucred *tgt,
    + struct user_namespace *ns)
    +{
    + if (src->user_ns != ns)
    + goto check_capable;
    + if (src->uid == tgt->uid || src->euid == tgt->uid ||
    + src->suid == tgt->uid)
    + return true;
    +check_capable:
    + if (ns_capable(ns, CAP_SETUID))
    + return true;
    + return false;
    +}
    +
    +static __inline__ bool gidequiv(struct cred *src, struct ucred *tgt,
    + struct user_namespace *ns)
    +{
    + if (src->user_ns != ns)
    + goto check_capable;
    + if (src->gid == tgt->gid || src->egid == tgt->gid ||
    + src->sgid == tgt->gid)
    + return true;
    +check_capable:
    + if (ns_capable(ns, CAP_SETGID))
    + return true;
    + return false;
    +}
    +
    +static __inline__ int scm_check_creds(struct ucred *creds, struct socket *sock)
    {
    const struct cred *cred = current_cred();
    + struct user_namespace *ns = sock_net(sock->sk)->user_ns;

    - if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) &&
    - ((creds->uid == cred->uid || creds->uid == cred->euid ||
    - creds->uid == cred->suid) || capable(CAP_SETUID)) &&
    - ((creds->gid == cred->gid || creds->gid == cred->egid ||
    - creds->gid == cred->sgid) || capable(CAP_SETGID))) {
    + if ((creds->pid == task_tgid_vnr(current) || ns_capable(ns, CAP_SYS_ADMIN)) &&
    + uidequiv(cred, creds, ns) && gidequiv(cred, creds, ns)) {
    return 0;
    }
    +
    return -EPERM;
    }

    @@ -169,7 +196,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
    if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct ucred)))
    goto error;
    memcpy(&p->creds, CMSG_DATA(cmsg), sizeof(struct ucred));
    - err = scm_check_creds(&p->creds);
    + err = scm_check_creds(&p->creds, sock);
    if (err)
    goto error;

    --
    1.7.4.1


    \
     
     \ /
      Last update: 2011-07-26 21:05    [W:0.100 / U:0.928 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site