tipc: allow non-linear first fragment buffer
The current code for message reassembly is erroneously assuming that the the first arriving fragment buffer always is linear, and then goes ahead resetting the fragment list of that buffer in anticipation of more arriving fragments. However, if the buffer already happens to be non-linear, we will inadvertently drop the already attached fragment list, and later on trig a BUG() in __pskb_pull_tail(). We see this happen when running fragmented TIPC multicast across UDP, something made possible since commitd0f91938be
("tipc: add ip/udp media type") We fix this by not resetting the fragment list when the buffer is non- linear, and by initiatlizing our private fragment list tail pointer to the tail of the existing fragment list. Fixes: commitd0f91938be
("tipc: add ip/udp media type") Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
1241365f1a
Коммит
45c8b7b175
|
@ -121,7 +121,7 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
|
|||
{
|
||||
struct sk_buff *head = *headbuf;
|
||||
struct sk_buff *frag = *buf;
|
||||
struct sk_buff *tail;
|
||||
struct sk_buff *tail = NULL;
|
||||
struct tipc_msg *msg;
|
||||
u32 fragid;
|
||||
int delta;
|
||||
|
@ -141,9 +141,15 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
|
|||
if (unlikely(skb_unclone(frag, GFP_ATOMIC)))
|
||||
goto err;
|
||||
head = *headbuf = frag;
|
||||
skb_frag_list_init(head);
|
||||
TIPC_SKB_CB(head)->tail = NULL;
|
||||
*buf = NULL;
|
||||
TIPC_SKB_CB(head)->tail = NULL;
|
||||
if (skb_is_nonlinear(head)) {
|
||||
skb_walk_frags(head, tail) {
|
||||
TIPC_SKB_CB(head)->tail = tail;
|
||||
}
|
||||
} else {
|
||||
skb_frag_list_init(head);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче