aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2013-04-03 13:28:16 -0400
committerDavid S. Miller <davem@davemloft.net>2013-04-07 18:58:55 -0400
commit6b0ee8c036ecb3ac92e18e6ca0dca7bff88beaf0 (patch)
treec32395b07fd0da960d26d8980f65ed8d97352165
parentd978a6361ad13f1f9694fcb7b5852d253a544d92 (diff)
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>
-rw-r--r--include/net/af_unix.h3
-rw-r--r--include/net/scm.h16
-rw-r--r--net/core/scm.c16
-rw-r--r--net/unix/af_unix.c16
4 files changed, 16 insertions, 35 deletions
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 0a996a3517ed..a8836e8445cc 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -29,7 +29,8 @@ struct unix_address {
29 29
30struct unix_skb_parms { 30struct unix_skb_parms {
31 struct pid *pid; /* Skb credentials */ 31 struct pid *pid; /* Skb credentials */
32 const struct cred *cred; 32 kuid_t uid;
33 kgid_t gid;
33 struct scm_fp_list *fp; /* Passed files */ 34 struct scm_fp_list *fp; /* Passed files */
34#ifdef CONFIG_SECURITY_NETWORK 35#ifdef CONFIG_SECURITY_NETWORK
35 u32 secid; /* Security ID */ 36 u32 secid; /* Security ID */
diff --git a/include/net/scm.h b/include/net/scm.h
index 975cca01048b..5a4c6a9eb122 100644
--- a/include/net/scm.h
+++ b/include/net/scm.h
@@ -26,7 +26,6 @@ struct scm_fp_list {
26 26
27struct scm_cookie { 27struct scm_cookie {
28 struct pid *pid; /* Skb credentials */ 28 struct pid *pid; /* Skb credentials */
29 const struct cred *cred;
30 struct scm_fp_list *fp; /* Passed files */ 29 struct scm_fp_list *fp; /* Passed files */
31 struct scm_creds creds; /* Skb credentials */ 30 struct scm_creds creds; /* Skb credentials */
32#ifdef CONFIG_SECURITY_NETWORK 31#ifdef CONFIG_SECURITY_NETWORK
@@ -51,23 +50,18 @@ static __inline__ void unix_get_peersec_dgram(struct socket *sock, struct scm_co
51#endif /* CONFIG_SECURITY_NETWORK */ 50#endif /* CONFIG_SECURITY_NETWORK */
52 51
53static __inline__ void scm_set_cred(struct scm_cookie *scm, 52static __inline__ void scm_set_cred(struct scm_cookie *scm,
54 struct pid *pid, const struct cred *cred) 53 struct pid *pid, kuid_t uid, kgid_t gid)
55{ 54{
56 scm->pid = get_pid(pid); 55 scm->pid = get_pid(pid);
57 scm->cred = cred ? get_cred(cred) : NULL;
58 scm->creds.pid = pid_vnr(pid); 56 scm->creds.pid = pid_vnr(pid);
59 scm->creds.uid = cred ? cred->euid : INVALID_UID; 57 scm->creds.uid = uid;
60 scm->creds.gid = cred ? cred->egid : INVALID_GID; 58 scm->creds.gid = gid;
61} 59}
62 60
63static __inline__ void scm_destroy_cred(struct scm_cookie *scm) 61static __inline__ void scm_destroy_cred(struct scm_cookie *scm)
64{ 62{
65 put_pid(scm->pid); 63 put_pid(scm->pid);
66 scm->pid = NULL; 64 scm->pid = NULL;
67
68 if (scm->cred)
69 put_cred(scm->cred);
70 scm->cred = NULL;
71} 65}
72 66
73static __inline__ void scm_destroy(struct scm_cookie *scm) 67static __inline__ void scm_destroy(struct scm_cookie *scm)
@@ -81,8 +75,10 @@ static __inline__ int scm_send(struct socket *sock, struct msghdr *msg,
81 struct scm_cookie *scm, bool forcecreds) 75 struct scm_cookie *scm, bool forcecreds)
82{ 76{
83 memset(scm, 0, sizeof(*scm)); 77 memset(scm, 0, sizeof(*scm));
78 scm->creds.uid = INVALID_UID;
79 scm->creds.gid = INVALID_GID;
84 if (forcecreds) 80 if (forcecreds)
85 scm_set_cred(scm, task_tgid(current), current_cred()); 81 scm_set_cred(scm, task_tgid(current), current_euid(), current_egid());
86 unix_get_peersec_dgram(sock, scm); 82 unix_get_peersec_dgram(sock, scm);
87 if (msg->msg_controllen <= 0) 83 if (msg->msg_controllen <= 0)
88 return 0; 84 return 0;
diff --git a/net/core/scm.c b/net/core/scm.c
index 2dc6cdaaae8a..83b2b383c865 100644
--- a/net/core/scm.c
+++ b/net/core/scm.c
@@ -187,22 +187,6 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p)
187 187
188 p->creds.uid = uid; 188 p->creds.uid = uid;
189 p->creds.gid = gid; 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 break; 190 break;
207 } 191 }
208 default: 192 default:
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 824eaf2c3afa..5ca1631de7ef 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1340,7 +1340,6 @@ static void unix_destruct_scm(struct sk_buff *skb)
1340 struct scm_cookie scm; 1340 struct scm_cookie scm;
1341 memset(&scm, 0, sizeof(scm)); 1341 memset(&scm, 0, sizeof(scm));
1342 scm.pid = UNIXCB(skb).pid; 1342 scm.pid = UNIXCB(skb).pid;
1343 scm.cred = UNIXCB(skb).cred;
1344 if (UNIXCB(skb).fp) 1343 if (UNIXCB(skb).fp)
1345 unix_detach_fds(&scm, skb); 1344 unix_detach_fds(&scm, skb);
1346 1345
@@ -1391,8 +1390,8 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
1391 int err = 0; 1390 int err = 0;
1392 1391
1393 UNIXCB(skb).pid = get_pid(scm->pid); 1392 UNIXCB(skb).pid = get_pid(scm->pid);
1394 if (scm->cred) 1393 UNIXCB(skb).uid = scm->creds.uid;
1395 UNIXCB(skb).cred = get_cred(scm->cred); 1394 UNIXCB(skb).gid = scm->creds.gid;
1396 UNIXCB(skb).fp = NULL; 1395 UNIXCB(skb).fp = NULL;
1397 if (scm->fp && send_fds) 1396 if (scm->fp && send_fds)
1398 err = unix_attach_fds(scm, skb); 1397 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
1409static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, 1408static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock,
1410 const struct sock *other) 1409 const struct sock *other)
1411{ 1410{
1412 if (UNIXCB(skb).cred) 1411 if (UNIXCB(skb).pid)
1413 return; 1412 return;
1414 if (test_bit(SOCK_PASSCRED, &sock->flags) || 1413 if (test_bit(SOCK_PASSCRED, &sock->flags) ||
1415 !other->sk_socket || 1414 !other->sk_socket ||
1416 test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { 1415 test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) {
1417 UNIXCB(skb).pid = get_pid(task_tgid(current)); 1416 UNIXCB(skb).pid = get_pid(task_tgid(current));
1418 UNIXCB(skb).cred = get_current_cred(); 1417 current_euid_egid(&UNIXCB(skb).uid, &UNIXCB(skb).gid);
1419 } 1418 }
1420} 1419}
1421 1420
@@ -1819,7 +1818,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1819 siocb->scm = &tmp_scm; 1818 siocb->scm = &tmp_scm;
1820 memset(&tmp_scm, 0, sizeof(tmp_scm)); 1819 memset(&tmp_scm, 0, sizeof(tmp_scm));
1821 } 1820 }
1822 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); 1821 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
1823 unix_set_secdata(siocb->scm, skb); 1822 unix_set_secdata(siocb->scm, skb);
1824 1823
1825 if (!(flags & MSG_PEEK)) { 1824 if (!(flags & MSG_PEEK)) {
@@ -1991,11 +1990,12 @@ again:
1991 if (check_creds) { 1990 if (check_creds) {
1992 /* Never glue messages from different writers */ 1991 /* Never glue messages from different writers */
1993 if ((UNIXCB(skb).pid != siocb->scm->pid) || 1992 if ((UNIXCB(skb).pid != siocb->scm->pid) ||
1994 (UNIXCB(skb).cred != siocb->scm->cred)) 1993 !uid_eq(UNIXCB(skb).uid, siocb->scm->creds.uid) ||
1994 !gid_eq(UNIXCB(skb).gid, siocb->scm->creds.gid))
1995 break; 1995 break;
1996 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { 1996 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
1997 /* Copy credentials */ 1997 /* Copy credentials */
1998 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred); 1998 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
1999 check_creds = 1; 1999 check_creds = 1;
2000 } 2000 }
2001 2001