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

asix: Fix small memory leak in ax88772_unbind()

When Ethernet frames span mulitple URBs, the netdev buffer memory
pointed to by the asix_rx_fixup_info structure remains allocated
during the time gap between the 2 executions of asix_rx_fixup_internal().

This means that if ax88772_unbind() is called within this time
gap to free the memory of the parent private data structure then
a memory leak of the part filled netdev buffer memory will occur.

Therefore, create a new function asix_rx_fixup_common_free() to
free the memory of the netdev buffer and add a call to
asix_rx_fixup_common_free() from inside ax88772_unbind().

Consequently when an unbind occurs part way through receiving
an Ethernet frame, the netdev buffer memory that is holding part
of the received Ethernet frame will now be freed.

Signed-off-by: Dean Jenkins <Dean_Jenkins@mentor.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Dean Jenkins and committed by
David S. Miller
d0c8f338 960eb4ee

+17
+1
drivers/net/usb/asix.h
··· 209 209 int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb, 210 210 struct asix_rx_fixup_info *rx); 211 211 int asix_rx_fixup_common(struct usbnet *dev, struct sk_buff *skb); 212 + void asix_rx_fixup_common_free(struct asix_common_private *dp); 212 213 213 214 struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, 214 215 gfp_t flags);
+15
drivers/net/usb/asix_common.c
··· 210 210 return asix_rx_fixup_internal(dev, skb, rx); 211 211 } 212 212 213 + void asix_rx_fixup_common_free(struct asix_common_private *dp) 214 + { 215 + struct asix_rx_fixup_info *rx; 216 + 217 + if (!dp) 218 + return; 219 + 220 + rx = &dp->rx_fixup_info; 221 + 222 + if (rx->ax_skb) { 223 + kfree_skb(rx->ax_skb); 224 + rx->ax_skb = NULL; 225 + } 226 + } 227 + 213 228 struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, 214 229 gfp_t flags) 215 230 {
+1
drivers/net/usb/asix_devices.c
··· 764 764 765 765 static void ax88772_unbind(struct usbnet *dev, struct usb_interface *intf) 766 766 { 767 + asix_rx_fixup_common_free(dev->driver_priv); 767 768 kfree(dev->driver_priv); 768 769 } 769 770