• Jon Paul Maloy's avatar
    tipc: compensate for double accounting in socket rcv buffer · 4f4482dc
    Jon Paul Maloy authored
    The function net/core/sock.c::__release_sock() runs a tight loop
    to move buffers from the socket backlog queue to the receive queue.
    
    As a security measure, sk_backlog.len of the receiving socket
    is not set to zero until after the loop is finished, i.e., until
    the whole backlog queue has been transferred to the receive queue.
    During this transfer, the data that has already been moved is counted
    both in the backlog queue and the receive queue, hence giving an
    incorrect picture of the available queue space for new arriving buffers.
    
    This leads to unnecessary rejection of buffers by sk_add_backlog(),
    which in TIPC leads to unnecessarily broken connections.
    
    In this commit, we compensate for this double accounting by adding
    a counter that keeps track of it. The function socket.c::backlog_rcv()
    receives buffers one by one from __release_sock(), and adds them to the
    socket receive queue. If the transfer is successful, it increases a new
    atomic counter 'tipc_sock::dupl_rcvcnt' with 'truesize' of the
    transferred buffer. If a new buffer arrives during this transfer and
    finds the socket busy (owned), we attempt to add it to the backlog.
    However, when sk_add_backlog() is called, we adjust the 'limit'
    parameter with the value of the new counter, so that the risk of
    inadvertent rejection is eliminated.
    
    It should be noted that this change does not invalidate the original
    purpose of zeroing 'sk_backlog.len' after the full transfer. We set an
    upper limit for dupl_rcvcnt, so that if a 'wild' sender (i.e., one that
    doesn't respect the send window) keeps pumping in buffers to
    sk_add_backlog(), he will eventually reach an upper limit,
    (2 x TIPC_CONN_OVERLOAD_LIMIT). After that, no messages can be added
    to the backlog, and the connection will be broken. Ordinary, well-
    behaved senders will never reach this buffer limit at all.
    Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
    Reviewed-by: default avatarYing Xue <ying.xue@windriver.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    4f4482dc
socket.c 51.3 KB