Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scm: Stop passing struct cred

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>

authored by

Eric W. Biederman and committed by
David S. Miller
6b0ee8c0 d978a636

+16 -35
+2 -1
include/net/af_unix.h
··· 29 29 30 30 struct unix_skb_parms { 31 31 struct pid *pid; /* Skb credentials */ 32 - const struct cred *cred; 32 + kuid_t uid; 33 + kgid_t gid; 33 34 struct scm_fp_list *fp; /* Passed files */ 34 35 #ifdef CONFIG_SECURITY_NETWORK 35 36 u32 secid; /* Security ID */
+6 -10
include/net/scm.h
··· 26 26 27 27 struct scm_cookie { 28 28 struct pid *pid; /* Skb credentials */ 29 - const struct cred *cred; 30 29 struct scm_fp_list *fp; /* Passed files */ 31 30 struct scm_creds creds; /* Skb credentials */ 32 31 #ifdef CONFIG_SECURITY_NETWORK ··· 50 51 #endif /* CONFIG_SECURITY_NETWORK */ 51 52 52 53 static __inline__ void scm_set_cred(struct scm_cookie *scm, 53 - struct pid *pid, const struct cred *cred) 54 + struct pid *pid, kuid_t uid, kgid_t gid) 54 55 { 55 56 scm->pid = get_pid(pid); 56 - scm->cred = cred ? get_cred(cred) : NULL; 57 57 scm->creds.pid = pid_vnr(pid); 58 - scm->creds.uid = cred ? cred->euid : INVALID_UID; 59 - scm->creds.gid = cred ? cred->egid : INVALID_GID; 58 + scm->creds.uid = uid; 59 + scm->creds.gid = gid; 60 60 } 61 61 62 62 static __inline__ void scm_destroy_cred(struct scm_cookie *scm) 63 63 { 64 64 put_pid(scm->pid); 65 65 scm->pid = NULL; 66 - 67 - if (scm->cred) 68 - put_cred(scm->cred); 69 - scm->cred = NULL; 70 66 } 71 67 72 68 static __inline__ void scm_destroy(struct scm_cookie *scm) ··· 75 81 struct scm_cookie *scm, bool forcecreds) 76 82 { 77 83 memset(scm, 0, sizeof(*scm)); 84 + scm->creds.uid = INVALID_UID; 85 + scm->creds.gid = INVALID_GID; 78 86 if (forcecreds) 79 - scm_set_cred(scm, task_tgid(current), current_cred()); 87 + scm_set_cred(scm, task_tgid(current), current_euid(), current_egid()); 80 88 unix_get_peersec_dgram(sock, scm); 81 89 if (msg->msg_controllen <= 0) 82 90 return 0;
-16
net/core/scm.c
··· 187 187 188 188 p->creds.uid = uid; 189 189 p->creds.gid = gid; 190 - 191 - if (!p->cred || 192 - !uid_eq(p->cred->euid, uid) || 193 - !gid_eq(p->cred->egid, gid)) { 194 - struct cred *cred; 195 - err = -ENOMEM; 196 - cred = prepare_creds(); 197 - if (!cred) 198 - goto error; 199 - 200 - cred->uid = cred->euid = uid; 201 - cred->gid = cred->egid = gid; 202 - if (p->cred) 203 - put_cred(p->cred); 204 - p->cred = cred; 205 - } 206 190 break; 207 191 } 208 192 default:
+8 -8
net/unix/af_unix.c
··· 1340 1340 struct scm_cookie scm; 1341 1341 memset(&scm, 0, sizeof(scm)); 1342 1342 scm.pid = UNIXCB(skb).pid; 1343 - scm.cred = UNIXCB(skb).cred; 1344 1343 if (UNIXCB(skb).fp) 1345 1344 unix_detach_fds(&scm, skb); 1346 1345 ··· 1390 1391 int err = 0; 1391 1392 1392 1393 UNIXCB(skb).pid = get_pid(scm->pid); 1393 - if (scm->cred) 1394 - UNIXCB(skb).cred = get_cred(scm->cred); 1394 + UNIXCB(skb).uid = scm->creds.uid; 1395 + UNIXCB(skb).gid = scm->creds.gid; 1395 1396 UNIXCB(skb).fp = NULL; 1396 1397 if (scm->fp && send_fds) 1397 1398 err = unix_attach_fds(scm, skb); ··· 1408 1409 static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, 1409 1410 const struct sock *other) 1410 1411 { 1411 - if (UNIXCB(skb).cred) 1412 + if (UNIXCB(skb).pid) 1412 1413 return; 1413 1414 if (test_bit(SOCK_PASSCRED, &sock->flags) || 1414 1415 !other->sk_socket || 1415 1416 test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { 1416 1417 UNIXCB(skb).pid = get_pid(task_tgid(current)); 1417 - UNIXCB(skb).cred = get_current_cred(); 1418 + current_euid_egid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); 1418 1419 } 1419 1420 } 1420 1421 ··· 1818 1819 siocb->scm = &tmp_scm; 1819 1820 memset(&tmp_scm, 0, sizeof(tmp_scm)); 1820 1821 } 1821 - scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); 1822 + scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); 1822 1823 unix_set_secdata(siocb->scm, skb); 1823 1824 1824 1825 if (!(flags & MSG_PEEK)) { ··· 1990 1991 if (check_creds) { 1991 1992 /* Never glue messages from different writers */ 1992 1993 if ((UNIXCB(skb).pid != siocb->scm->pid) || 1993 - (UNIXCB(skb).cred != siocb->scm->cred)) 1994 + !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) || 1995 + !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid)) 1994 1996 break; 1995 1997 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { 1996 1998 /* Copy credentials */ 1997 - scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); 1999 + scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); 1998 2000 check_creds = 1; 1999 2001 } 2000 2002