scm: Stop passing struct cred
authorEric W. Biederman <ebiederm@xmission.com>
Wed, 3 Apr 2013 17:28:16 +0000 (17:28 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 7 Apr 2013 22:58:55 +0000 (18:58 -0400)
Now that uids and gids are completely encapsulated in kuid_t
and kgid_t we no longer need to pass struct cred which allowed
us to test both the uid and the user namespace for equality.

Passing struct cred potentially allows us to pass the entire group
list as BSD does but I don't believe the cost of cache line misses
justifies retaining code for a future potential application.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/af_unix.h
include/net/scm.h
net/core/scm.c
net/unix/af_unix.c

index 0a996a3517edd2e652bb389ca4093d9928e7b974..a8836e8445ccf412c219b06bf9a9a4371fe959f5 100644 (file)
@@ -29,7 +29,8 @@ struct unix_address {
 
 struct unix_skb_parms {
        struct pid              *pid;           /* Skb credentials      */
-       const struct cred       *cred;
+       kuid_t                  uid;
+       kgid_t                  gid;
        struct scm_fp_list      *fp;            /* Passed files         */
 #ifdef CONFIG_SECURITY_NETWORK
        u32                     secid;          /* Security ID          */
index 975cca01048bee3b7da9017725654053921250ae..5a4c6a9eb12258449abad265eda33692ab00f908 100644 (file)
@@ -26,7 +26,6 @@ struct scm_fp_list {
 
 struct scm_cookie {
        struct pid              *pid;           /* Skb credentials */
-       const struct cred       *cred;
        struct scm_fp_list      *fp;            /* Passed files         */
        struct scm_creds        creds;          /* Skb credentials      */
 #ifdef CONFIG_SECURITY_NETWORK
@@ -51,23 +50,18 @@ static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_co
 #endif /* CONFIG_SECURITY_NETWORK */
 
 static __inline__ void scm_set_cred(struct scm_cookie *scm,
-                                   struct pid *pid, const struct cred *cred)
+                                   struct pid *pid, kuid_t uid, kgid_t gid)
 {
        scm->pid  = get_pid(pid);
-       scm->cred = cred ? get_cred(cred) : NULL;
        scm->creds.pid = pid_vnr(pid);
-       scm->creds.uid = cred ? cred->euid : INVALID_UID;
-       scm->creds.gid = cred ? cred->egid : INVALID_GID;
+       scm->creds.uid = uid;
+       scm->creds.gid = gid;
 }
 
 static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
 {
        put_pid(scm->pid);
        scm->pid  = NULL;
-
-       if (scm->cred)
-               put_cred(scm->cred);
-       scm->cred = NULL;
 }
 
 static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -81,8 +75,10 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
                               struct scm_cookie *scm, bool forcecreds)
 {
        memset(scm, 0, sizeof(*scm));
+       scm->creds.uid = INVALID_UID;
+       scm->creds.gid = INVALID_GID;
        if (forcecreds)
-               scm_set_cred(scm, task_tgid(current), current_cred());
+               scm_set_cred(scm, task_tgid(current), current_euid(), current_egid());
        unix_get_peersec_dgram(sock, scm);
        if (msg->msg_controllen <= 0)
                return 0;
index 2dc6cdaaae8abc5f31afa57a7ccf765cc978b6ac..83b2b383c86582346e0c779c745a822bf8341ca6 100644 (file)
@@ -187,22 +187,6 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
 
                        p->creds.uid = uid;
                        p->creds.gid = gid;
-
-                       if (!p->cred ||
-                           !uid_eq(p->cred->euid, uid) ||
-                           !gid_eq(p->cred->egid, gid)) {
-                               struct cred *cred;
-                               err = -ENOMEM;
-                               cred = prepare_creds();
-                               if (!cred)
-                                       goto error;
-
-                               cred->uid = cred->euid = uid;
-                               cred->gid = cred->egid = gid;
-                               if (p->cred)
-                                       put_cred(p->cred);
-                               p->cred = cred;
-                       }
                        break;
                }
                default:
index 824eaf2c3afa9fa65954f91757d897ca0d289eda..5ca1631de7ef365da21ff689210e69c74047c079 100644 (file)
@@ -1340,7 +1340,6 @@ static void unix_destruct_scm(struct sk_buff *skb)
        struct scm_cookie scm;
        memset(&scm, 0, sizeof(scm));
        scm.pid  = UNIXCB(skb).pid;
-       scm.cred = UNIXCB(skb).cred;
        if (UNIXCB(skb).fp)
                unix_detach_fds(&scm, skb);
 
@@ -1391,8 +1390,8 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
        int err = 0;
 
        UNIXCB(skb).pid  = get_pid(scm->pid);
-       if (scm->cred)
-               UNIXCB(skb).cred = get_cred(scm->cred);
+       UNIXCB(skb).uid = scm->creds.uid;
+       UNIXCB(skb).gid = scm->creds.gid;
        UNIXCB(skb).fp = NULL;
        if (scm->fp && send_fds)
                err = unix_attach_fds(scm, skb);
@@ -1409,13 +1408,13 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
 static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
                            const struct sock *other)
 {
-       if (UNIXCB(skb).cred)
+       if (UNIXCB(skb).pid)
                return;
        if (test_bit(SOCK_PASSCRED, &sock->flags) ||
            !other->sk_socket ||
            test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
                UNIXCB(skb).pid  = get_pid(task_tgid(current));
-               UNIXCB(skb).cred = get_current_cred();
+               current_euid_egid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
        }
 }
 
@@ -1819,7 +1818,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
                siocb->scm = &tmp_scm;
                memset(&tmp_scm, 0, sizeof(tmp_scm));
        }
-       scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
+       scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
        unix_set_secdata(siocb->scm, skb);
 
        if (!(flags & MSG_PEEK)) {
@@ -1991,11 +1990,12 @@ again:
                if (check_creds) {
                        /* Never glue messages from different writers */
                        if ((UNIXCB(skb).pid  != siocb->scm->pid) ||
-                           (UNIXCB(skb).cred != siocb->scm->cred))
+                           !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) ||
+                           !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid))
                                break;
                } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
                        /* Copy credentials */
-                       scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
+                       scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
                        check_creds = 1;
                }