aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/af_unix.c
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2008-11-13 19:29:12 -0500
committerJames Morris <jmorris@namei.org>2008-11-13 19:29:12 -0500
commit2b828925652340277a889cbc11b2d0637f7cdaf7 (patch)
tree32fcb3d3e466fc419fad2d3717956a5b5ad3d35a /net/unix/af_unix.c
parent3a3b7ce9336952ea7b9564d976d068a238976c9d (diff)
parent58e20d8d344b0ee083febb18c2b021d2427e56ca (diff)
Merge branch 'master' into next
Conflicts: security/keys/internal.h security/keys/process_keys.c security/keys/request_key.c Fixed conflicts above by using the non 'tsk' versions. Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'net/unix/af_unix.c')
-rw-r--r--net/unix/af_unix.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 338c1aec7089..2775acbca199 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1301,14 +1301,23 @@ static void unix_destruct_fds(struct sk_buff *skb)
1301 sock_wfree(skb); 1301 sock_wfree(skb);
1302} 1302}
1303 1303
1304static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) 1304static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1305{ 1305{
1306 int i; 1306 int i;
1307
1308 /*
1309 * Need to duplicate file references for the sake of garbage
1310 * collection. Otherwise a socket in the fps might become a
1311 * candidate for GC while the skb is not yet queued.
1312 */
1313 UNIXCB(skb).fp = scm_fp_dup(scm->fp);
1314 if (!UNIXCB(skb).fp)
1315 return -ENOMEM;
1316
1307 for (i=scm->fp->count-1; i>=0; i--) 1317 for (i=scm->fp->count-1; i>=0; i--)
1308 unix_inflight(scm->fp->fp[i]); 1318 unix_inflight(scm->fp->fp[i]);
1309 UNIXCB(skb).fp = scm->fp;
1310 skb->destructor = unix_destruct_fds; 1319 skb->destructor = unix_destruct_fds;
1311 scm->fp = NULL; 1320 return 0;
1312} 1321}
1313 1322
1314/* 1323/*
@@ -1367,8 +1376,11 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1367 goto out; 1376 goto out;
1368 1377
1369 memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); 1378 memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
1370 if (siocb->scm->fp) 1379 if (siocb->scm->fp) {
1371 unix_attach_fds(siocb->scm, skb); 1380 err = unix_attach_fds(siocb->scm, skb);
1381 if (err)
1382 goto out_free;
1383 }
1372 unix_get_secdata(siocb->scm, skb); 1384 unix_get_secdata(siocb->scm, skb);
1373 1385
1374 skb_reset_transport_header(skb); 1386 skb_reset_transport_header(skb);
@@ -1537,8 +1549,13 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1537 size = min_t(int, size, skb_tailroom(skb)); 1549 size = min_t(int, size, skb_tailroom(skb));
1538 1550
1539 memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred)); 1551 memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
1540 if (siocb->scm->fp) 1552 if (siocb->scm->fp) {
1541 unix_attach_fds(siocb->scm, skb); 1553 err = unix_attach_fds(siocb->scm, skb);
1554 if (err) {
1555 kfree_skb(skb);
1556 goto out_err;
1557 }
1558 }
1542 1559
1543 if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) { 1560 if ((err = memcpy_fromiovec(skb_put(skb,size), msg->msg_iov, size)) != 0) {
1544 kfree_skb(skb); 1561 kfree_skb(skb);