Commit 29322d0db98e5a84f5cc6a55655bee3dc4ffb5ab
Committed by
David S. Miller
1 parent
b6e195fd4f
tipc: fix bug in multicast/broadcast message reassembly
Since commit 37e22164a8a3c39bdad45aa463b1e69a1fdf4110 ("tipc: rename and move message reassembly function") reassembly of long broadcast messages has been broken. This is because we test for a non-NULL return value of the *buf parameter as criteria for succesful reassembly. However, this parameter is left defined even after reception of the first fragment, when reassebly is still incomplete. This leads to a kernel crash as soon as a the first fragment of a long broadcast message is received. We fix this with this commit, by implementing a stricter behavior of the function and its return values. This commit should be applied to both net and net-next. Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Acked-by: Ying Xue <ying.xue@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 8 additions and 3 deletions Side-by-side Diff
net/tipc/msg.c
... | ... | @@ -101,9 +101,11 @@ |
101 | 101 | } |
102 | 102 | |
103 | 103 | /* tipc_buf_append(): Append a buffer to the fragment list of another buffer |
104 | - * Let first buffer become head buffer | |
105 | - * Returns 1 and sets *buf to headbuf if chain is complete, otherwise 0 | |
106 | - * Leaves headbuf pointer at NULL if failure | |
104 | + * @*headbuf: in: NULL for first frag, otherwise value returned from prev call | |
105 | + * out: set when successful non-complete reassembly, otherwise NULL | |
106 | + * @*buf: in: the buffer to append. Always defined | |
107 | + * out: head buf after sucessful complete reassembly, otherwise NULL | |
108 | + * Returns 1 when reassembly complete, otherwise 0 | |
107 | 109 | */ |
108 | 110 | int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) |
109 | 111 | { |
... | ... | @@ -122,6 +124,7 @@ |
122 | 124 | goto out_free; |
123 | 125 | head = *headbuf = frag; |
124 | 126 | skb_frag_list_init(head); |
127 | + *buf = NULL; | |
125 | 128 | return 0; |
126 | 129 | } |
127 | 130 | if (!head) |
... | ... | @@ -150,6 +153,8 @@ |
150 | 153 | out_free: |
151 | 154 | pr_warn_ratelimited("Unable to build fragment list\n"); |
152 | 155 | kfree_skb(*buf); |
156 | + kfree_skb(*headbuf); | |
157 | + *buf = *headbuf = NULL; | |
153 | 158 | return 0; |
154 | 159 | } |