]> www.infradead.org Git - users/hch/misc.git/commitdiff
af_unix: Set drop reason in unix_dgram_disconnected().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Thu, 16 Jan 2025 05:34:40 +0000 (14:34 +0900)
committerJakub Kicinski <kuba@kernel.org>
Mon, 20 Jan 2025 19:27:41 +0000 (11:27 -0800)
unix_dgram_disconnected() is called from two places:

  1. when a connect()ed socket dis-connect()s or re-connect()s to
     another socket

  2. when sendmsg() fails because the peer socket that the client
     has connect()ed to has been close()d

Then, the client's recv queue is purged to remove all messages from
the old peer socket.

Let's define a new drop reason for that case.

  # echo 1 > /sys/kernel/tracing/events/skb/kfree_skb/enable

  # python3
  >>> from socket import *
  >>>
  >>> # s1 has a message from s2
  >>> s1, s2 = socketpair(AF_UNIX, SOCK_DGRAM)
  >>> s2.send(b'hello world')
  >>>
  >>> # re-connect() drops the message from s2
  >>> s3 = socket(AF_UNIX, SOCK_DGRAM)
  >>> s3.bind('')
  >>> s1.connect(s3.getsockname())

  # cat /sys/kernel/tracing/trace_pipe
     python3-250 ... kfree_skb: ... location=skb_queue_purge_reason+0xdc/0x110 reason: UNIX_DISCONNECT

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://patch.msgid.link/20250116053441.5758-8-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/dropreason-core.h
net/unix/af_unix.c

index d6c9d841eb11368ed98449fa4a369c95b2bc5c79..32a34dfe8cc58fb1afda8922a52249080f1183b5 100644 (file)
@@ -9,6 +9,7 @@
        FN(SOCKET_CLOSE)                \
        FN(SOCKET_FILTER)               \
        FN(SOCKET_RCVBUFF)              \
+       FN(UNIX_DISCONNECT)             \
        FN(UNIX_SKIP_OOB)               \
        FN(PKT_TOO_SMALL)               \
        FN(TCP_CSUM)                    \
@@ -146,6 +147,12 @@ enum skb_drop_reason {
        SKB_DROP_REASON_SOCKET_FILTER,
        /** @SKB_DROP_REASON_SOCKET_RCVBUFF: socket receive buff is full */
        SKB_DROP_REASON_SOCKET_RCVBUFF,
+       /**
+        * @SKB_DROP_REASON_UNIX_DISCONNECT: recv queue is purged when SOCK_DGRAM
+        * or SOCK_SEQPACKET socket re-connect()s to another socket or notices
+        * during send() that the peer has been close()d.
+        */
+       SKB_DROP_REASON_UNIX_DISCONNECT,
        /**
         * @SKB_DROP_REASON_UNIX_SKIP_OOB: Out-Of-Band data is skipped by
         * recv() without MSG_OOB so dropped.
index de4966e1b7ff95a4eecb8c2ba29a318c65d6459a..5e1b408c19daf6868d36dc52508cdef9e9b5d982 100644 (file)
@@ -622,7 +622,9 @@ static void unix_write_space(struct sock *sk)
 static void unix_dgram_disconnected(struct sock *sk, struct sock *other)
 {
        if (!skb_queue_empty(&sk->sk_receive_queue)) {
-               skb_queue_purge(&sk->sk_receive_queue);
+               skb_queue_purge_reason(&sk->sk_receive_queue,
+                                      SKB_DROP_REASON_UNIX_DISCONNECT);
+
                wake_up_interruptible_all(&unix_sk(sk)->peer_wait);
 
                /* If one link of bidirectional dgram pipe is disconnected,