• Michal Luczaj's avatar
    af_unix: Fix garbage collection of embryos carrying OOB with SCM_RIGHTS · 041933a1
    Michal Luczaj authored
    GC attempts to explicitly drop oob_skb's reference before purging the hit
    list.
    
    The problem is with embryos: kfree_skb(u->oob_skb) is never called on an
    embryo socket.
    
    The python script below [0] sends a listener's fd to its embryo as OOB
    data.  While GC does collect the embryo's queue, it fails to drop the OOB
    skb's refcount.  The skb which was in embryo's receive queue stays as
    unix_sk(sk)->oob_skb and keeps the listener's refcount [1].
    
    Tell GC to dispose embryo's oob_skb.
    
    [0]:
    from array import array
    from socket import *
    
    addr = '\x00unix-oob'
    lis = socket(AF_UNIX, SOCK_STREAM)
    lis.bind(addr)
    lis.listen(1)
    
    s = socket(AF_UNIX, SOCK_STREAM)
    s.connect(addr)
    scm = (SOL_SOCKET, SCM_RIGHTS, array('i', [lis.fileno()]))
    s.sendmsg([b'x'], [scm], MSG_OOB)
    lis.close()
    
    [1]
    $ grep unix-oob /proc/net/unix
    $ ./unix-oob.py
    $ grep unix-oob /proc/net/unix
    0000000000000000: 00000002 00000000 00000000 0001 02     0 @unix-oob
    0000000000000000: 00000002 00000000 00010000 0001 01  6072 @unix-oob
    
    Fixes: 4090fa37 ("af_unix: Replace garbage collection algorithm.")
    Signed-off-by: default avatarMichal Luczaj <mhal@rbox.co>
    Reviewed-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
    Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
    041933a1
garbage.c 15.8 KB