linux/net/tipc
Jon Paul Maloy 4f4482dcd9 tipc: compensate for double accounting in socket rcv buffer
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: Jon Maloy <jon.maloy@ericsson.com>
Reviewed-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2014-05-14 15:19:47 -04:00
..
addr.c tipc: compress out gratuitous extra carriage returns 2012-04-30 15:53:56 -04:00
addr.h tipc: explicitly include core.h in addr.h 2014-02-13 17:49:13 -05:00
bcast.c tipc: avoid to asynchronously reset all links 2014-05-05 17:26:45 -04:00
bcast.h tipc: avoid to asynchronously reset all links 2014-05-05 17:26:45 -04:00
bearer.c tipc: fix race in disc create/delete 2014-04-22 21:17:53 -04:00
bearer.h tipc: use RCU to protect media_ptr pointer 2014-04-22 21:17:53 -04:00
config.c tipc: convert allocations of global variables associated with bclink 2014-05-05 17:26:45 -04:00
config.h tipc: obsolete the remote management feature 2014-03-27 13:08:36 -04:00
core.c tipc: decrease connection flow control window 2014-05-14 15:19:47 -04:00
core.h tipc: purge signal handler infrastructure 2014-05-05 17:26:45 -04:00
discover.c tipc: fix a possible memory leak 2014-04-27 19:08:06 -04:00
discover.h tipc: fix race in disc create/delete 2014-04-22 21:17:53 -04:00
eth_media.c tipc: eliminate code duplication in media layer 2013-12-11 00:17:43 -05:00
ib_media.c tipc: eliminate code duplication in media layer 2013-12-11 00:17:43 -05:00
Kconfig tipc: add InfiniBand media type 2013-04-17 14:18:33 -04:00
link.c tipc: don't directly overwrite node action_flags 2014-05-09 01:41:01 -04:00
link.h tipc: avoid to asynchronously reset all links 2014-05-05 17:26:45 -04:00
log.c tipc: remove print_buf and deprecated log buffer code 2012-07-13 19:34:43 -04:00
Makefile tipc: purge signal handler infrastructure 2014-05-05 17:26:45 -04:00
msg.c tipc: remove iovec length parameter from all sending functions 2013-10-18 13:20:42 -04:00
msg.h tipc: message reassembly using fragment chain 2013-11-07 18:30:11 -05:00
name_distr.c tipc: avoid to asynchronously deliver name tables to peer node 2014-05-05 17:26:44 -04:00
name_distr.h tipc: avoid to asynchronously deliver name tables to peer node 2014-05-05 17:26:44 -04:00
name_table.c tipc: fix memory leak of publications 2014-04-30 13:31:26 -04:00
name_table.h tipc: cosmetic realignment of function arguments 2013-06-17 15:53:01 -07:00
net.c tipc: convert allocations of global variables associated with bclink 2014-05-05 17:26:45 -04:00
net.h tipc: convert allocations of global variables associated with bclink 2014-05-05 17:26:45 -04:00
netlink.c net: Use netlink_ns_capable to verify the permisions of netlink messages 2014-04-24 13:44:54 -04:00
node_subscr.c tipc: avoid to asynchronously notify subscriptions 2014-05-05 17:26:44 -04:00
node_subscr.h tipc: avoid to asynchronously notify subscriptions 2014-05-05 17:26:44 -04:00
node.c tipc: don't directly overwrite node action_flags 2014-05-09 01:41:01 -04:00
node.h tipc: rename enum names of node flags 2014-05-09 01:41:01 -04:00
port.c tipc: eliminate redundant lookups in registry 2014-03-12 15:53:49 -04:00
port.h tipc: decrease connection flow control window 2014-05-14 15:19:47 -04:00
ref.c tipc: eliminate redundant lookups in registry 2014-03-12 15:53:49 -04:00
ref.h tipc: eliminate redundant lookups in registry 2014-03-12 15:53:49 -04:00
server.c net: Fix use after free by removing length arg from sk_data_ready callbacks. 2014-04-11 16:15:36 -04:00
server.h tipc: remove all enabled flags from all tipc components 2014-02-22 00:00:15 -05:00
socket.c tipc: compensate for double accounting in socket rcv buffer 2014-05-14 15:19:47 -04:00
socket.h tipc: compensate for double accounting in socket rcv buffer 2014-05-14 15:19:47 -04:00
subscr.c tipc: fix spinlock recursion bug for failed subscriptions 2014-03-24 15:36:56 -04:00
subscr.h tipc: cosmetic realignment of function arguments 2013-06-17 15:53:01 -07:00
sysctl.c tipc: change socket buffer overflow control to respect sk_rcvbuf 2013-06-17 15:53:00 -07:00