diff options
author | James Morris <jmorris@namei.org> | 2008-11-13 19:29:12 -0500 |
---|---|---|
committer | James Morris <jmorris@namei.org> | 2008-11-13 19:29:12 -0500 |
commit | 2b828925652340277a889cbc11b2d0637f7cdaf7 (patch) | |
tree | 32fcb3d3e466fc419fad2d3717956a5b5ad3d35a /net/unix/af_unix.c | |
parent | 3a3b7ce9336952ea7b9564d976d068a238976c9d (diff) | |
parent | 58e20d8d344b0ee083febb18c2b021d2427e56ca (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.c | 31 |
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 | ||
1304 | static void unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) | 1304 | static 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); |