diff options
author | Jesper Juhl <jj@chaosbits.net> | 2011-01-13 15:53:38 -0500 |
---|---|---|
committer | Sven Eckelmann <sven@narfation.org> | 2011-01-13 16:11:12 -0500 |
commit | ed7809d9c41b514115ddffaa860694393c2016b3 (patch) | |
tree | ef0e14d7477b2363f787ace24b683a439ea103f2 /net | |
parent | 53320fe3bb1b1eef1aaff8dd47aae530ebeeb1e5 (diff) |
batman-adv: Even Batman should not dereference NULL pointers
There's a problem in net/batman-adv/unicast.c::frag_send_skb().
dev_alloc_skb() allocates memory and may fail, thus returning NULL. If
this happens we'll pass a NULL pointer on to skb_split() which in turn
hands it to skb_split_inside_header() from where it gets passed to
skb_put() that lets skb_tail_pointer() play with it and that function
dereferences it. And thus the bat dies.
While I was at it I also moved the call to dev_alloc_skb() above the
assignment to 'unicast_packet' since there's no reason to do that
assignment if the memory allocation fails.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Signed-off-by: Sven Eckelmann <sven@narfation.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/batman-adv/unicast.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/net/batman-adv/unicast.c b/net/batman-adv/unicast.c index dc2e28bed844..ee41fef04b21 100644 --- a/net/batman-adv/unicast.c +++ b/net/batman-adv/unicast.c | |||
@@ -229,10 +229,12 @@ int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, | |||
229 | if (!bat_priv->primary_if) | 229 | if (!bat_priv->primary_if) |
230 | goto dropped; | 230 | goto dropped; |
231 | 231 | ||
232 | unicast_packet = (struct unicast_packet *) skb->data; | 232 | frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); |
233 | if (!frag_skb) | ||
234 | goto dropped; | ||
233 | 235 | ||
236 | unicast_packet = (struct unicast_packet *) skb->data; | ||
234 | memcpy(&tmp_uc, unicast_packet, uc_hdr_len); | 237 | memcpy(&tmp_uc, unicast_packet, uc_hdr_len); |
235 | frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); | ||
236 | skb_split(skb, frag_skb, data_len / 2); | 238 | skb_split(skb, frag_skb, data_len / 2); |
237 | 239 | ||
238 | if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || | 240 | if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || |