diff options
-rw-r--r-- | include/net/af_unix.h | 3 | ||||
-rw-r--r-- | include/net/scm.h | 16 | ||||
-rw-r--r-- | net/core/scm.c | 16 | ||||
-rw-r--r-- | net/unix/af_unix.c | 16 |
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 | ||
30 | struct unix_skb_parms { | 30 | struct 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 | ||
27 | struct scm_cookie { | 27 | struct 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 | ||
53 | static __inline__ void scm_set_cred(struct scm_cookie *scm, | 52 | static __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 | ||
63 | static __inline__ void scm_destroy_cred(struct scm_cookie *scm) | 61 | static __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 | ||
73 | static __inline__ void scm_destroy(struct scm_cookie *scm) | 67 | static __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 | |||
1409 | static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, | 1408 | static 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 | ||