• Kuniyuki Iwashima's avatar
    af_unix: Don't stop recv(MSG_DONTWAIT) if consumed OOB skb is at the head. · 93c99f21
    Kuniyuki Iwashima authored
    Let's say a socket send()s "hello" with MSG_OOB and "world" without flags,
    
      >>> from socket import *
      >>> c1, c2 = socketpair(AF_UNIX)
      >>> c1.send(b'hello', MSG_OOB)
      5
      >>> c1.send(b'world')
      5
    
    and its peer recv()s "hell" and "o".
    
      >>> c2.recv(10)
      b'hell'
      >>> c2.recv(1, MSG_OOB)
      b'o'
    
    Now the consumed OOB skb stays at the head of recvq to return a correct
    value for ioctl(SIOCATMARK), which is broken now and fixed by a later
    patch.
    
    Then, if peer issues recv() with MSG_DONTWAIT, manage_oob() returns NULL,
    so recv() ends up with -EAGAIN.
    
      >>> c2.setblocking(False)  # This causes -EAGAIN even with available data
      >>> c2.recv(5)
      Traceback (most recent call last):
        File "<stdin>", line 1, in <module>
      BlockingIOError: [Errno 11] Resource temporarily unavailable
    
    However, next recv() will return the following available data, "world".
    
      >>> c2.recv(5)
      b'world'
    
    When the consumed OOB skb is at the head of the queue, we need to fetch
    the next skb to fix the weird behaviour.
    
    Note that the issue does not happen without MSG_DONTWAIT because we can
    retry after manage_oob().
    
    This patch also adds a test case that covers the issue.
    
    Without fix:
    
      #  RUN           msg_oob.no_peek.ex_oob_break ...
      # msg_oob.c:134:ex_oob_break:AF_UNIX :Resource temporarily unavailable
      # msg_oob.c:135:ex_oob_break:Expected:ld
      # msg_oob.c:137:ex_oob_break:Expected ret[0] (-1) == expected_len (2)
      # ex_oob_break: Test terminated by assertion
      #          FAIL  msg_oob.no_peek.ex_oob_break
      not ok 8 msg_oob.no_peek.ex_oob_break
    
    With fix:
    
      #  RUN           msg_oob.no_peek.ex_oob_break ...
      #            OK  msg_oob.no_peek.ex_oob_break
      ok 8 msg_oob.no_peek.ex_oob_break
    
    Fixes: 314001f0 ("af_unix: Add OOB support")
    Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
    Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
    93c99f21
msg_oob.c 5.42 KB