@@ -1316,18 +1316,20 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1316
1316
int i ;
1317
1317
1318
1318
scm -> fp = UNIXCB (skb ).fp ;
1319
- skb -> destructor = sock_wfree ;
1320
1319
UNIXCB (skb ).fp = NULL ;
1321
1320
1322
1321
for (i = scm -> fp -> count - 1 ; i >= 0 ; i -- )
1323
1322
unix_notinflight (scm -> fp -> fp [i ]);
1324
1323
}
1325
1324
1326
- static void unix_destruct_fds (struct sk_buff * skb )
1325
+ static void unix_destruct_scm (struct sk_buff * skb )
1327
1326
{
1328
1327
struct scm_cookie scm ;
1329
1328
memset (& scm , 0 , sizeof (scm ));
1330
- unix_detach_fds (& scm , skb );
1329
+ scm .pid = UNIXCB (skb ).pid ;
1330
+ scm .cred = UNIXCB (skb ).cred ;
1331
+ if (UNIXCB (skb ).fp )
1332
+ unix_detach_fds (& scm , skb );
1331
1333
1332
1334
/* Alas, it calls VFS */
1333
1335
/* So fscking what? fput() had been SMP-safe since the last Summer */
@@ -1350,10 +1352,22 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
1350
1352
1351
1353
for (i = scm -> fp -> count - 1 ; i >= 0 ; i -- )
1352
1354
unix_inflight (scm -> fp -> fp [i ]);
1353
- skb -> destructor = unix_destruct_fds ;
1354
1355
return 0 ;
1355
1356
}
1356
1357
1358
+ static int unix_scm_to_skb (struct scm_cookie * scm , struct sk_buff * skb , bool send_fds )
1359
+ {
1360
+ int err = 0 ;
1361
+ UNIXCB (skb ).pid = get_pid (scm -> pid );
1362
+ UNIXCB (skb ).cred = get_cred (scm -> cred );
1363
+ UNIXCB (skb ).fp = NULL ;
1364
+ if (scm -> fp && send_fds )
1365
+ err = unix_attach_fds (scm , skb );
1366
+
1367
+ skb -> destructor = unix_destruct_scm ;
1368
+ return err ;
1369
+ }
1370
+
1357
1371
/*
1358
1372
* Send AF_UNIX data.
1359
1373
*/
@@ -1410,12 +1424,9 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
1410
1424
if (skb == NULL )
1411
1425
goto out ;
1412
1426
1413
- memcpy (UNIXCREDS (skb ), & siocb -> scm -> creds , sizeof (struct ucred ));
1414
- if (siocb -> scm -> fp ) {
1415
- err = unix_attach_fds (siocb -> scm , skb );
1416
- if (err )
1417
- goto out_free ;
1418
- }
1427
+ err = unix_scm_to_skb (siocb -> scm , skb , true);
1428
+ if (err )
1429
+ goto out_free ;
1419
1430
unix_get_secdata (siocb -> scm , skb );
1420
1431
1421
1432
skb_reset_transport_header (skb );
@@ -1585,16 +1596,14 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
1585
1596
*/
1586
1597
size = min_t (int , size , skb_tailroom (skb ));
1587
1598
1588
- memcpy ( UNIXCREDS ( skb ), & siocb -> scm -> creds , sizeof ( struct ucred ));
1599
+
1589
1600
/* Only send the fds in the first buffer */
1590
- if (siocb -> scm -> fp && !fds_sent ) {
1591
- err = unix_attach_fds (siocb -> scm , skb );
1592
- if (err ) {
1593
- kfree_skb (skb );
1594
- goto out_err ;
1595
- }
1596
- fds_sent = true;
1601
+ err = unix_scm_to_skb (siocb -> scm , skb , !fds_sent );
1602
+ if (err ) {
1603
+ kfree_skb (skb );
1604
+ goto out_err ;
1597
1605
}
1606
+ fds_sent = true;
1598
1607
1599
1608
err = memcpy_fromiovec (skb_put (skb , size ), msg -> msg_iov , size );
1600
1609
if (err ) {
@@ -1711,7 +1720,7 @@ static int unix_dgram_recvmsg(struct kiocb *iocb, struct socket *sock,
1711
1720
siocb -> scm = & tmp_scm ;
1712
1721
memset (& tmp_scm , 0 , sizeof (tmp_scm ));
1713
1722
}
1714
- siocb -> scm -> creds = * UNIXCREDS (skb );
1723
+ scm_set_cred ( siocb -> scm , UNIXCB ( skb ). pid , UNIXCB (skb ). cred );
1715
1724
unix_set_secdata (siocb -> scm , skb );
1716
1725
1717
1726
if (!(flags & MSG_PEEK )) {
@@ -1860,14 +1869,14 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
1860
1869
1861
1870
if (check_creds ) {
1862
1871
/* Never glue messages from different writers */
1863
- if (memcmp ( UNIXCREDS (skb ), & siocb -> scm -> creds ,
1864
- sizeof ( siocb -> scm -> creds )) != 0 ) {
1872
+ if (( UNIXCB (skb ). pid != siocb -> scm -> pid ) ||
1873
+ ( UNIXCB ( skb ). cred != siocb -> scm -> cred ) ) {
1865
1874
skb_queue_head (& sk -> sk_receive_queue , skb );
1866
1875
break ;
1867
1876
}
1868
1877
} else {
1869
1878
/* Copy credentials */
1870
- siocb -> scm -> creds = * UNIXCREDS (skb );
1879
+ scm_set_cred ( siocb -> scm , UNIXCB ( skb ). pid , UNIXCB (skb ). cred );
1871
1880
check_creds = 1 ;
1872
1881
}
1873
1882
0 commit comments