diff options
author | Jesper Juhl <jj@chaosbits.net> | 2011-01-13 06:40:11 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-14 00:48:26 -0500 |
commit | 9e56790ad31d72a5a44142af462d047c0c897b29 (patch) | |
tree | 0557144779a2ad51093110dce0cdc163592e15fb /drivers/net/usb | |
parent | e84f885ebfb43b1ebb1481ee8bb2018743f947e9 (diff) |
USB CDC NCM: Don't deref NULL in cdc_ncm_rx_fixup() and don't use uninitialized variable.
skb_clone() dynamically allocates memory and may fail. If it does it
returns NULL. This means we'll dereference a NULL pointer in
drivers/net/usb/cdc_ncm.c::cdc_ncm_rx_fixup().
As far as I can tell, the proper way to deal with this is simply to goto
the error label.
Furthermore gcc complains that 'skb' may be used uninitialized:
drivers/net/usb/cdc_ncm.c: In function ‘cdc_ncm_rx_fixup’:
drivers/net/usb/cdc_ncm.c:922:18: warning: ‘skb’ may be used uninitialized in this function
and I believe it is right. On the line where we
pr_debug("invalid frame detected (ignored)" ...
we are using the local variable 'skb' but nothing has ever been assigned
to that variable yet. I believe the correct fix for that is to use
'skb_in' instead.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r-- | drivers/net/usb/cdc_ncm.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 593c104ab199..d776c4a8d3c1 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -1021,13 +1021,15 @@ static int cdc_ncm_rx_fixup(struct usbnet *dev, struct sk_buff *skb_in) | |||
1021 | (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) { | 1021 | (temp > CDC_NCM_MAX_DATAGRAM_SIZE) || (temp < ETH_HLEN)) { |
1022 | pr_debug("invalid frame detected (ignored)" | 1022 | pr_debug("invalid frame detected (ignored)" |
1023 | "offset[%u]=%u, length=%u, skb=%p\n", | 1023 | "offset[%u]=%u, length=%u, skb=%p\n", |
1024 | x, offset, temp, skb); | 1024 | x, offset, temp, skb_in); |
1025 | if (!x) | 1025 | if (!x) |
1026 | goto error; | 1026 | goto error; |
1027 | break; | 1027 | break; |
1028 | 1028 | ||
1029 | } else { | 1029 | } else { |
1030 | skb = skb_clone(skb_in, GFP_ATOMIC); | 1030 | skb = skb_clone(skb_in, GFP_ATOMIC); |
1031 | if (!skb) | ||
1032 | goto error; | ||
1031 | skb->len = temp; | 1033 | skb->len = temp; |
1032 | skb->data = ((u8 *)skb_in->data) + offset; | 1034 | skb->data = ((u8 *)skb_in->data) + offset; |
1033 | skb_set_tail_pointer(skb, temp); | 1035 | skb_set_tail_pointer(skb, temp); |