Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tipc: unclone unbundled buffers before forwarding

When extracting an individual message from a received "bundle" buffer,
we just create a clone of the base buffer, and adjust it to point into
the right position of the linearized data area of the latter. This works
well for regular message reception, but during periods of extremely high
load it may happen that an extracted buffer, e.g, a connection probe, is
reversed and forwarded through an external interface while the preceding
extracted message is still unhandled. When this happens, the header or
data area of the preceding message will be partially overwritten by a
MAC header, leading to unpredicatable consequences, such as a link
reset.

We now fix this by ensuring that the msg_reverse() function never
returns a cloned buffer, and that the returned buffer always contains
sufficient valid head and tail room to be forwarded.

Reported-by: Erik Hugne <erik.hugne@gmail.com>
Acked-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jon Paul Maloy and committed by
David S. Miller
27777daa d19af0a7

+6 -11
+6
net/tipc/msg.c
··· 41 41 #include "name_table.h" 42 42 43 43 #define MAX_FORWARD_SIZE 1024 44 + #define BUF_HEADROOM (LL_MAX_HEADER + 48) 45 + #define BUF_TAILROOM 16 44 46 45 47 static unsigned int align(unsigned int i) 46 48 { ··· 506 504 memcpy(hdr, &ohdr, BASIC_H_SIZE); 507 505 msg_set_hdr_sz(hdr, BASIC_H_SIZE); 508 506 } 507 + 508 + if (skb_cloned(_skb) && 509 + pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_KERNEL)) 510 + goto exit; 509 511 510 512 /* Now reverse the concerned fields */ 511 513 msg_set_errcode(hdr, err);
-11
net/tipc/msg.h
··· 94 94 95 95 #define TIPC_MEDIA_INFO_OFFSET 5 96 96 97 - /** 98 - * TIPC message buffer code 99 - * 100 - * TIPC message buffer headroom reserves space for the worst-case 101 - * link-level device header (in case the message is sent off-node). 102 - * 103 - * Note: Headroom should be a multiple of 4 to ensure the TIPC header fields 104 - * are word aligned for quicker access 105 - */ 106 - #define BUF_HEADROOM (LL_MAX_HEADER + 48) 107 - 108 97 struct tipc_skb_cb { 109 98 void *handle; 110 99 struct sk_buff *tail;