aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2015-06-10 08:44:59 -0400
committerDavid S. Miller <davem@davemloft.net>2015-06-11 01:49:20 -0400
commit37a9a8df8ce9de6ea73349c9ac8bdf6ba4ec4f70 (patch)
tree255b2d8c931e665feabf697cfd28f633f44232ea /net/unix/af_unix.c
parentbae23b6840a6a15947173d8282028458dbcdeb5b (diff)
net/unix: support SCM_SECURITY for stream sockets
SCM_SECURITY was originally only implemented for datagram sockets, not for stream sockets. However, SCM_CREDENTIALS is supported on Unix stream sockets. For consistency, implement Unix stream support for SCM_SECURITY as well. Also clean up the existing code and get rid of the superfluous UNIXSID macro. Motivated by https://bugzilla.redhat.com/show_bug.cgi?id=1224211, where systemd was using SCM_CREDENTIALS and assumed wrongly that SCM_SECURITY was also supported on Unix stream sockets. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Acked-by: Paul Moore <paul@paul-moore.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index f25e1675b865..03ee4d359f6a 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -140,12 +140,17 @@ static struct hlist_head *unix_sockets_unbound(void *addr)
140#ifdef CONFIG_SECURITY_NETWORK 140#ifdef CONFIG_SECURITY_NETWORK
141static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) 141static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
142{ 142{
143 memcpy(UNIXSID(skb), &scm->secid, sizeof(u32)); 143 UNIXCB(skb).secid = scm->secid;
144} 144}
145 145
146static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) 146static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
147{ 147{
148 scm->secid = *UNIXSID(skb); 148 scm->secid = UNIXCB(skb).secid;
149}
150
151static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
152{
153 return (scm->secid == UNIXCB(skb).secid);
149} 154}
150#else 155#else
151static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb) 156static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
@@ -153,6 +158,11 @@ static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
153 158
154static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb) 159static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
155{ } 160{ }
161
162static inline bool unix_secdata_eq(struct scm_cookie *scm, struct sk_buff *skb)
163{
164 return true;
165}
156#endif /* CONFIG_SECURITY_NETWORK */ 166#endif /* CONFIG_SECURITY_NETWORK */
157 167
158/* 168/*
@@ -1414,6 +1424,7 @@ static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool sen
1414 UNIXCB(skb).uid = scm->creds.uid; 1424 UNIXCB(skb).uid = scm->creds.uid;
1415 UNIXCB(skb).gid = scm->creds.gid; 1425 UNIXCB(skb).gid = scm->creds.gid;
1416 UNIXCB(skb).fp = NULL; 1426 UNIXCB(skb).fp = NULL;
1427 unix_get_secdata(scm, skb);
1417 if (scm->fp && send_fds) 1428 if (scm->fp && send_fds)
1418 err = unix_attach_fds(scm, skb); 1429 err = unix_attach_fds(scm, skb);
1419 1430
@@ -1509,7 +1520,6 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
1509 if (err < 0) 1520 if (err < 0)
1510 goto out_free; 1521 goto out_free;
1511 max_level = err + 1; 1522 max_level = err + 1;
1512 unix_get_secdata(&scm, skb);
1513 1523
1514 skb_put(skb, len - data_len); 1524 skb_put(skb, len - data_len);
1515 skb->data_len = data_len; 1525 skb->data_len = data_len;
@@ -2118,11 +2128,13 @@ unlock:
2118 /* Never glue messages from different writers */ 2128 /* Never glue messages from different writers */
2119 if ((UNIXCB(skb).pid != scm.pid) || 2129 if ((UNIXCB(skb).pid != scm.pid) ||
2120 !uid_eq(UNIXCB(skb).uid, scm.creds.uid) || 2130 !uid_eq(UNIXCB(skb).uid, scm.creds.uid) ||
2121 !gid_eq(UNIXCB(skb).gid, scm.creds.gid)) 2131 !gid_eq(UNIXCB(skb).gid, scm.creds.gid) ||
2132 !unix_secdata_eq(&scm, skb))
2122 break; 2133 break;
2123 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) { 2134 } else if (test_bit(SOCK_PASSCRED, &sock->flags)) {
2124 /* Copy credentials */ 2135 /* Copy credentials */
2125 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid); 2136 scm_set_cred(&scm, UNIXCB(skb).pid, UNIXCB(skb).uid, UNIXCB(skb).gid);
2137 unix_set_secdata(&scm, skb);
2126 check_creds = true; 2138 check_creds = true;
2127 } 2139 }
2128 2140