@@ -503,6 +503,12 @@ static void unix_sock_destructor(struct sock *sk)
503
503
504
504
skb_queue_purge (& sk -> sk_receive_queue );
505
505
506
+ #if IS_ENABLED (CONFIG_AF_UNIX_OOB )
507
+ if (u -> oob_skb ) {
508
+ kfree_skb (u -> oob_skb );
509
+ u -> oob_skb = NULL ;
510
+ }
511
+ #endif
506
512
WARN_ON (refcount_read (& sk -> sk_wmem_alloc ));
507
513
WARN_ON (!sk_unhashed (sk ));
508
514
WARN_ON (sk -> sk_socket );
@@ -1889,6 +1895,46 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
1889
1895
*/
1890
1896
#define UNIX_SKB_FRAGS_SZ (PAGE_SIZE << get_order(32768))
1891
1897
1898
+ #if (IS_ENABLED (CONFIG_AF_UNIX_OOB ))
1899
+ static int queue_oob (struct socket * sock , struct msghdr * msg , struct sock * other )
1900
+ {
1901
+ struct unix_sock * ousk = unix_sk (other );
1902
+ struct sk_buff * skb ;
1903
+ int err = 0 ;
1904
+
1905
+ skb = sock_alloc_send_skb (sock -> sk , 1 , msg -> msg_flags & MSG_DONTWAIT , & err );
1906
+
1907
+ if (!skb )
1908
+ return err ;
1909
+
1910
+ skb_put (skb , 1 );
1911
+ skb -> len = 1 ;
1912
+ err = skb_copy_datagram_from_iter (skb , 0 , & msg -> msg_iter , 1 );
1913
+
1914
+ if (err ) {
1915
+ kfree_skb (skb );
1916
+ return err ;
1917
+ }
1918
+
1919
+ unix_state_lock (other );
1920
+ maybe_add_creds (skb , sock , other );
1921
+ skb_get (skb );
1922
+
1923
+ if (ousk -> oob_skb )
1924
+ kfree_skb (ousk -> oob_skb );
1925
+
1926
+ ousk -> oob_skb = skb ;
1927
+
1928
+ scm_stat_add (other , skb );
1929
+ skb_queue_tail (& other -> sk_receive_queue , skb );
1930
+ sk_send_sigurg (other );
1931
+ unix_state_unlock (other );
1932
+ other -> sk_data_ready (other );
1933
+
1934
+ return err ;
1935
+ }
1936
+ #endif
1937
+
1892
1938
static int unix_stream_sendmsg (struct socket * sock , struct msghdr * msg ,
1893
1939
size_t len )
1894
1940
{
@@ -1907,8 +1953,14 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1907
1953
return err ;
1908
1954
1909
1955
err = - EOPNOTSUPP ;
1910
- if (msg -> msg_flags & MSG_OOB )
1911
- goto out_err ;
1956
+ if (msg -> msg_flags & MSG_OOB ) {
1957
+ #if (IS_ENABLED (CONFIG_AF_UNIX_OOB ))
1958
+ if (len )
1959
+ len -- ;
1960
+ else
1961
+ #endif
1962
+ goto out_err ;
1963
+ }
1912
1964
1913
1965
if (msg -> msg_namelen ) {
1914
1966
err = sk -> sk_state == TCP_ESTABLISHED ? - EISCONN : - EOPNOTSUPP ;
@@ -1973,6 +2025,15 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
1973
2025
sent += size ;
1974
2026
}
1975
2027
2028
+ #if (IS_ENABLED (CONFIG_AF_UNIX_OOB ))
2029
+ if (msg -> msg_flags & MSG_OOB ) {
2030
+ err = queue_oob (sock , msg , other );
2031
+ if (err )
2032
+ goto out_err ;
2033
+ sent ++ ;
2034
+ }
2035
+ #endif
2036
+
1976
2037
scm_destroy (& scm );
1977
2038
1978
2039
return sent ;
@@ -2358,6 +2419,59 @@ struct unix_stream_read_state {
2358
2419
unsigned int splice_flags ;
2359
2420
};
2360
2421
2422
+ #if IS_ENABLED (CONFIG_AF_UNIX_OOB )
2423
+ static int unix_stream_recv_urg (struct unix_stream_read_state * state )
2424
+ {
2425
+ struct socket * sock = state -> socket ;
2426
+ struct sock * sk = sock -> sk ;
2427
+ struct unix_sock * u = unix_sk (sk );
2428
+ int chunk = 1 ;
2429
+
2430
+ if (sock_flag (sk , SOCK_URGINLINE ) || !u -> oob_skb )
2431
+ return - EINVAL ;
2432
+
2433
+ chunk = state -> recv_actor (u -> oob_skb , 0 , chunk , state );
2434
+ if (chunk < 0 )
2435
+ return - EFAULT ;
2436
+
2437
+ if (!(state -> flags & MSG_PEEK )) {
2438
+ UNIXCB (u -> oob_skb ).consumed += 1 ;
2439
+ kfree_skb (u -> oob_skb );
2440
+ u -> oob_skb = NULL ;
2441
+ }
2442
+ state -> msg -> msg_flags |= MSG_OOB ;
2443
+ return 1 ;
2444
+ }
2445
+
2446
+ static struct sk_buff * manage_oob (struct sk_buff * skb , struct sock * sk ,
2447
+ int flags , int copied )
2448
+ {
2449
+ struct unix_sock * u = unix_sk (sk );
2450
+
2451
+ if (!unix_skb_len (skb ) && !(flags & MSG_PEEK )) {
2452
+ skb_unlink (skb , & sk -> sk_receive_queue );
2453
+ consume_skb (skb );
2454
+ skb = NULL ;
2455
+ } else {
2456
+ if (skb == u -> oob_skb ) {
2457
+ if (copied ) {
2458
+ skb = NULL ;
2459
+ } else if (sock_flag (sk , SOCK_URGINLINE )) {
2460
+ if (!(flags & MSG_PEEK )) {
2461
+ u -> oob_skb = NULL ;
2462
+ consume_skb (skb );
2463
+ }
2464
+ } else if (!(flags & MSG_PEEK )) {
2465
+ skb_unlink (skb , & sk -> sk_receive_queue );
2466
+ consume_skb (skb );
2467
+ skb = skb_peek (& sk -> sk_receive_queue );
2468
+ }
2469
+ }
2470
+ }
2471
+ return skb ;
2472
+ }
2473
+ #endif
2474
+
2361
2475
static int unix_stream_read_generic (struct unix_stream_read_state * state ,
2362
2476
bool freezable )
2363
2477
{
@@ -2383,6 +2497,15 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
2383
2497
2384
2498
if (unlikely (flags & MSG_OOB )) {
2385
2499
err = - EOPNOTSUPP ;
2500
+ #if IS_ENABLED (CONFIG_AF_UNIX_OOB )
2501
+ mutex_lock (& u -> iolock );
2502
+ unix_state_lock (sk );
2503
+
2504
+ err = unix_stream_recv_urg (state );
2505
+
2506
+ unix_state_unlock (sk );
2507
+ mutex_unlock (& u -> iolock );
2508
+ #endif
2386
2509
goto out ;
2387
2510
}
2388
2511
@@ -2411,6 +2534,18 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
2411
2534
}
2412
2535
last = skb = skb_peek (& sk -> sk_receive_queue );
2413
2536
last_len = last ? last -> len : 0 ;
2537
+
2538
+ #if IS_ENABLED (CONFIG_AF_UNIX_OOB )
2539
+ if (skb ) {
2540
+ skb = manage_oob (skb , sk , flags , copied );
2541
+ if (!skb ) {
2542
+ unix_state_unlock (sk );
2543
+ if (copied )
2544
+ break ;
2545
+ goto redo ;
2546
+ }
2547
+ }
2548
+ #endif
2414
2549
again :
2415
2550
if (skb == NULL ) {
2416
2551
if (copied >= target )
@@ -2746,6 +2881,20 @@ static int unix_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
2746
2881
case SIOCUNIXFILE :
2747
2882
err = unix_open_file (sk );
2748
2883
break ;
2884
+ #if IS_ENABLED (CONFIG_AF_UNIX_OOB )
2885
+ case SIOCATMARK :
2886
+ {
2887
+ struct sk_buff * skb ;
2888
+ struct unix_sock * u = unix_sk (sk );
2889
+ int answ = 0 ;
2890
+
2891
+ skb = skb_peek (& sk -> sk_receive_queue );
2892
+ if (skb && skb == u -> oob_skb )
2893
+ answ = 1 ;
2894
+ err = put_user (answ , (int __user * )arg );
2895
+ }
2896
+ break ;
2897
+ #endif
2749
2898
default :
2750
2899
err = - ENOIOCTLCMD ;
2751
2900
break ;
0 commit comments