• Kuniyuki Iwashima's avatar
    af_unix: Remove scm_fp_dup() in unix_attach_fds(). · 7c349ed0
    Kuniyuki Iwashima authored
    When we passed fds, we used to bump each file's refcount twice
    in scm_fp_copy() and scm_fp_dup() before linking the socket to
    gc_inflight_list.
    
    This is because we incremented the inflight count of the socket
    and linked it to the list in advance before passing skb to the
    destination socket.
    
    Otherwise, the inflight socket could have been garbage-collected
    in a small race window between linking the socket to the list and
    queuing skb:
    
      CPU 1 : sendmsg(X) w/ A's fd     CPU 2 : close(A)
      -----                            -----
      /* Here A's refcount is 1, and inflight count is 0 */
    
      bump A's refcount to 2 in scm_fp_copy()
      bump A's inflight count to 1
      link A to gc_inflight_list
                                       decrement A's refcount to 1
    
      /* A's refcount == inflight count, thus A could be GC candidate */
    
                                       start GC
                                       mark A as candidate
                                       purge A's receive queue
    
      queue skb w/ A's fd to X
    
      /* A is queued, but all data has been lost */
    
    After commit 4090fa37 ("af_unix: Replace garbage collection
    algorithm."), we increment the inflight count and link the socket
    to the global list only when queuing the skb.
    
    The race no longer exists, so let's not clone the fd nor bump
    the count in unix_attach_fds().
    Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
    Link: https://lore.kernel.org/r/20240401173125.92184-2-kuniyu@amazon.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    7c349ed0
af_unix.c 87.9 KB