aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c114
1 files changed, 74 insertions, 40 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index fef2cc5e9d2b..0b39b2451ea5 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -282,7 +282,7 @@ static inline struct sock *unix_find_socket_byname(struct net *net,
282 return s; 282 return s;
283} 283}
284 284
285static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i) 285static struct sock *unix_find_socket_byinode(struct inode *i)
286{ 286{
287 struct sock *s; 287 struct sock *s;
288 struct hlist_node *node; 288 struct hlist_node *node;
@@ -292,9 +292,6 @@ static struct sock *unix_find_socket_byinode(struct net *net, struct inode *i)
292 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) { 292 &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
293 struct dentry *dentry = unix_sk(s)->dentry; 293 struct dentry *dentry = unix_sk(s)->dentry;
294 294
295 if (!net_eq(sock_net(s), net))
296 continue;
297
298 if (dentry && dentry->d_inode == i) { 295 if (dentry && dentry->d_inode == i) {
299 sock_hold(s); 296 sock_hold(s);
300 goto found; 297 goto found;
@@ -450,11 +447,31 @@ static int unix_release_sock(struct sock *sk, int embrion)
450 return 0; 447 return 0;
451} 448}
452 449
450static void init_peercred(struct sock *sk)
451{
452 put_pid(sk->sk_peer_pid);
453 if (sk->sk_peer_cred)
454 put_cred(sk->sk_peer_cred);
455 sk->sk_peer_pid = get_pid(task_tgid(current));
456 sk->sk_peer_cred = get_current_cred();
457}
458
459static void copy_peercred(struct sock *sk, struct sock *peersk)
460{
461 put_pid(sk->sk_peer_pid);
462 if (sk->sk_peer_cred)
463 put_cred(sk->sk_peer_cred);
464 sk->sk_peer_pid = get_pid(peersk->sk_peer_pid);
465 sk->sk_peer_cred = get_cred(peersk->sk_peer_cred);
466}
467
453static int unix_listen(struct socket *sock, int backlog) 468static int unix_listen(struct socket *sock, int backlog)
454{ 469{
455 int err; 470 int err;
456 struct sock *sk = sock->sk; 471 struct sock *sk = sock->sk;
457 struct unix_sock *u = unix_sk(sk); 472 struct unix_sock *u = unix_sk(sk);
473 struct pid *old_pid = NULL;
474 const struct cred *old_cred = NULL;
458 475
459 err = -EOPNOTSUPP; 476 err = -EOPNOTSUPP;
460 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET) 477 if (sock->type != SOCK_STREAM && sock->type != SOCK_SEQPACKET)
@@ -470,12 +487,14 @@ static int unix_listen(struct socket *sock, int backlog)
470 sk->sk_max_ack_backlog = backlog; 487 sk->sk_max_ack_backlog = backlog;
471 sk->sk_state = TCP_LISTEN; 488 sk->sk_state = TCP_LISTEN;
472 /* set credentials so connect can copy them */ 489 /* set credentials so connect can copy them */
473 sk->sk_peercred.pid = task_tgid_vnr(current); 490 init_peercred(sk);
474 current_euid_egid(&sk->sk_peercred.uid, &sk->sk_peercred.gid);
475 err = 0; 491 err = 0;
476 492
477out_unlock: 493out_unlock:
478 unix_state_unlock(sk); 494 unix_state_unlock(sk);
495 put_pid(old_pid);
496 if (old_cred)
497 put_cred(old_cred);
479out: 498out:
480 return err; 499 return err;
481} 500}
@@ -673,6 +692,7 @@ static int unix_autobind(struct socket *sock)
673 static u32 ordernum = 1; 692 static u32 ordernum = 1;
674 struct unix_address *addr; 693 struct unix_address *addr;
675 int err; 694 int err;
695 unsigned int retries = 0;
676 696
677 mutex_lock(&u->readlock); 697 mutex_lock(&u->readlock);
678 698
@@ -698,9 +718,17 @@ retry:
698 if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type, 718 if (__unix_find_socket_byname(net, addr->name, addr->len, sock->type,
699 addr->hash)) { 719 addr->hash)) {
700 spin_unlock(&unix_table_lock); 720 spin_unlock(&unix_table_lock);
701 /* Sanity yield. It is unusual case, but yet... */ 721 /*
702 if (!(ordernum&0xFF)) 722 * __unix_find_socket_byname() may take long time if many names
703 yield(); 723 * are already in use.
724 */
725 cond_resched();
726 /* Give up if all names seems to be in use. */
727 if (retries++ == 0xFFFFF) {
728 err = -ENOSPC;
729 kfree(addr);
730 goto out;
731 }
704 goto retry; 732 goto retry;
705 } 733 }
706 addr->hash ^= sk->sk_type; 734 addr->hash ^= sk->sk_type;
@@ -736,7 +764,7 @@ static struct sock *unix_find_other(struct net *net,
736 err = -ECONNREFUSED; 764 err = -ECONNREFUSED;
737 if (!S_ISSOCK(inode->i_mode)) 765 if (!S_ISSOCK(inode->i_mode))
738 goto put_fail; 766 goto put_fail;
739 u = unix_find_socket_byinode(net, inode); 767 u = unix_find_socket_byinode(inode);
740 if (!u) 768 if (!u)
741 goto put_fail; 769 goto put_fail;
742 770
@@ -1140,8 +1168,7 @@ restart:
1140 unix_peer(newsk) = sk; 1168 unix_peer(newsk) = sk;
1141 newsk->sk_state = TCP_ESTABLISHED; 1169 newsk->sk_state = TCP_ESTABLISHED;
1142 newsk->sk_type = sk->sk_type; 1170 newsk->sk_type = sk->sk_type;
1143 newsk->sk_peercred.pid = task_tgid_vnr(current); 1171 init_peercred(newsk);
1144 current_euid_egid(&newsk->sk_peercred.uid, &newsk->sk_peercred.gid);
1145 newu = unix_sk(newsk); 1172 newu = unix_sk(newsk);
1146 newsk->sk_wq = &newu->peer_wq; 1173 newsk->sk_wq = &newu->peer_wq;
1147 otheru = unix_sk(other); 1174 otheru = unix_sk(other);
@@ -1157,7 +1184,7 @@ restart:
1157 } 1184 }
1158 1185
1159 /* Set credentials */ 1186 /* Set credentials */
1160 sk->sk_peercred = other->sk_peercred; 1187 copy_peercred(sk, other);
1161 1188
1162 sock->state = SS_CONNECTED; 1189 sock->state = SS_CONNECTED;
1163 sk->sk_state = TCP_ESTABLISHED; 1190 sk->sk_state = TCP_ESTABLISHED;
@@ -1199,10 +1226,8 @@ static int unix_socketpair(struct socket *socka, struct socket *sockb)
1199 sock_hold(skb); 1226 sock_hold(skb);
1200 unix_peer(ska) = skb; 1227 unix_peer(ska) = skb;
1201 unix_peer(skb) = ska; 1228 unix_peer(skb) = ska;
1202 ska->sk_peercred.pid = skb->sk_peercred.pid = task_tgid_vnr(current); 1229 init_peercred(ska);
1203 current_euid_egid(&skb->sk_peercred.uid, &skb->sk_peercred.gid); 1230 init_peercred(skb);
1204 ska->sk_peercred.uid = skb->sk_peercred.uid;
1205 ska->sk_peercred.gid = skb->sk_peercred.gid;
1206 1231
1207 if (ska->sk_type != SOCK_DGRAM) { 1232 if (ska->sk_type != SOCK_DGRAM) {
1208 ska->sk_state = TCP_ESTABLISHED; 1233 ska->sk_state = TCP_ESTABLISHED;
@@ -1297,18 +1322,20 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1297 int i; 1322 int i;
1298 1323
1299 scm->fp = UNIXCB(skb).fp; 1324 scm->fp = UNIXCB(skb).fp;
1300 skb->destructor = sock_wfree;
1301 UNIXCB(skb).fp = NULL; 1325 UNIXCB(skb).fp = NULL;
1302 1326
1303 for (i = scm->fp->count-1; i >= 0; i--) 1327 for (i = scm->fp->count-1; i >= 0; i--)
1304 unix_notinflight(scm->fp->fp[i]); 1328 unix_notinflight(scm->fp->fp[i]);
1305} 1329}
1306 1330
1307static void unix_destruct_fds(struct sk_buff *skb) 1331static void unix_destruct_scm(struct sk_buff *skb)
1308{ 1332{
1309 struct scm_cookie scm; 1333 struct scm_cookie scm;
1310 memset(&scm, 0, sizeof(scm)); 1334 memset(&scm, 0, sizeof(scm));
1311 unix_detach_fds(&scm, skb); 1335 scm.pid = UNIXCB(skb).pid;
1336 scm.cred = UNIXCB(skb).cred;
1337 if (UNIXCB(skb).fp)
1338 unix_detach_fds(&scm, skb);
1312 1339
1313 /* Alas, it calls VFS */ 1340 /* Alas, it calls VFS */
1314 /* So fscking what? fput() had been SMP-safe since the last Summer */ 1341 /* So fscking what? fput() had been SMP-safe since the last Summer */
@@ -1331,10 +1358,22 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1331 1358
1332 for (i = scm->fp->count-1; i >= 0; i--) 1359 for (i = scm->fp->count-1; i >= 0; i--)
1333 unix_inflight(scm->fp->fp[i]); 1360 unix_inflight(scm->fp->fp[i]);
1334 skb->destructor = unix_destruct_fds;
1335 return 0; 1361 return 0;
1336} 1362}
1337 1363
1364static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
1365{
1366 int err = 0;
1367 UNIXCB(skb).pid = get_pid(scm->pid);
1368 UNIXCB(skb).cred = get_cred(scm->cred);
1369 UNIXCB(skb).fp = NULL;
1370 if (scm->fp && send_fds)
1371 err = unix_attach_fds(scm, skb);
1372
1373 skb->destructor = unix_destruct_scm;
1374 return err;
1375}
1376
1338/* 1377/*
1339 * Send AF_UNIX data. 1378 * Send AF_UNIX data.
1340 */ 1379 */
@@ -1391,12 +1430,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1391 if (skb == NULL) 1430 if (skb == NULL)
1392 goto out; 1431 goto out;
1393 1432
1394 memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); 1433 err = unix_scm_to_skb(siocb->scm, skb, true);
1395 if (siocb->scm->fp) { 1434 if (err)
1396 err = unix_attach_fds(siocb->scm, skb); 1435 goto out_free;
1397 if (err)
1398 goto out_free;
1399 }
1400 unix_get_secdata(siocb->scm, skb); 1436 unix_get_secdata(siocb->scm, skb);
1401 1437
1402 skb_reset_transport_header(skb); 1438 skb_reset_transport_header(skb);
@@ -1566,16 +1602,14 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1566 */ 1602 */
1567 size = min_t(int, size, skb_tailroom(skb)); 1603 size = min_t(int, size, skb_tailroom(skb));
1568 1604
1569 memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); 1605
1570 /* Only send the fds in the first buffer */ 1606 /* Only send the fds in the first buffer */
1571 if (siocb->scm->fp && !fds_sent) { 1607 err = unix_scm_to_skb(siocb->scm, skb, !fds_sent);
1572 err = unix_attach_fds(siocb->scm, skb); 1608 if (err) {
1573 if (err) { 1609 kfree_skb(skb);
1574 kfree_skb(skb); 1610 goto out_err;
1575 goto out_err;
1576 }
1577 fds_sent = true;
1578 } 1611 }
1612 fds_sent = true;
1579 1613
1580 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); 1614 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
1581 if (err) { 1615 if (err) {
@@ -1692,7 +1726,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1692 siocb->scm = &tmp_scm; 1726 siocb->scm = &tmp_scm;
1693 memset(&tmp_scm, 0, sizeof(tmp_scm)); 1727 memset(&tmp_scm, 0, sizeof(tmp_scm));
1694 } 1728 }
1695 siocb->scm->creds = *UNIXCREDS(skb); 1729 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
1696 unix_set_secdata(siocb->scm, skb); 1730 unix_set_secdata(siocb->scm, skb);
1697 1731
1698 if (!(flags & MSG_PEEK)) { 1732 if (!(flags & MSG_PEEK)) {
@@ -1841,14 +1875,14 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1841 1875
1842 if (check_creds) { 1876 if (check_creds) {
1843 /* Never glue messages from different writers */ 1877 /* Never glue messages from different writers */
1844 if (memcmp(UNIXCREDS(skb), &siocb->scm->creds, 1878 if ((UNIXCB(skb).pid != siocb->scm->pid) ||
1845 sizeof(siocb->scm->creds)) != 0) { 1879 (UNIXCB(skb).cred != siocb->scm->cred)) {
1846 skb_queue_head(&sk->sk_receive_queue, skb); 1880 skb_queue_head(&sk->sk_receive_queue, skb);
1847 break; 1881 break;
1848 } 1882 }
1849 } else { 1883 } else {
1850 /* Copy credentials */ 1884 /* Copy credentials */
1851 siocb->scm->creds = *UNIXCREDS(skb); 1885 scm_set_cred(siocb->scm, UNIXCB(skb).pid, UNIXCB(skb).cred);
1852 check_creds = 1; 1886 check_creds = 1;
1853 } 1887 }
1854 1888
@@ -1881,7 +1915,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1881 break; 1915 break;
1882 } 1916 }
1883 1917
1884 kfree_skb(skb); 1918 consume_skb(skb);
1885 1919
1886 if (siocb->scm->fp) 1920 if (siocb->scm->fp)
1887 break; 1921 break;