Skip to content

Commit d1bde92

Browse files
oleremvijay-suman
authored andcommitted
net: usb: lan78xx: Fix double free issue with interrupt buffer allocation
In lan78xx_probe(), the buffer `buf` was being freed twice: once implicitly through `usb_free_urb(dev->urb_intr)` with the `URB_FREE_BUFFER` flag and again explicitly by `kfree(buf)`. This caused a double free issue. To resolve this, reordered `kmalloc()` and `usb_alloc_urb()` calls to simplify the initialization sequence and removed the redundant `kfree(buf)`. Now, `buf` is allocated after `usb_alloc_urb()`, ensuring it is correctly managed by `usb_fill_int_urb()` and freed by `usb_free_urb()` as intended. Fixes: a6df95c ("lan78xx: Fix memory allocation bug") Cc: John Efstathiades <[email protected]> Signed-off-by: Oleksij Rempel <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Orabug: 37433573 CVE: CVE-2024-53213 (cherry picked from commit 03819ab) cherry-pick-repo=kernel/git/torvalds/linux.git Conflicts: drivers/net/usb/lan78xx.c A small contextual conflict as UEK7 doesn't have the upstream commit: e13adbf ("net: remove third argument of usb_maxpacket()") Signed-off-by: Qing Huang <[email protected]> Reviewed-by: Harshit Mogalapalli <[email protected]> Signed-off-by: Vijayendra Suman <[email protected]>
1 parent bf11791 commit d1bde92

File tree

1 file changed

+14
-15
lines changed

1 file changed

+14
-15
lines changed

drivers/net/usb/lan78xx.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4407,37 +4407,38 @@ static int lan78xx_probe(struct usb_interface *intf,
44074407

44084408
period = ep_intr->desc.bInterval;
44094409
maxp = usb_maxpacket(dev->udev, dev->pipe_intr, 0);
4410-
buf = kmalloc(maxp, GFP_KERNEL);
4411-
if (!buf) {
4410+
4411+
dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
4412+
if (!dev->urb_intr) {
44124413
ret = -ENOMEM;
44134414
goto out5;
44144415
}
44154416

4416-
dev->urb_intr = usb_alloc_urb(0, GFP_KERNEL);
4417-
if (!dev->urb_intr) {
4417+
buf = kmalloc(maxp, GFP_KERNEL);
4418+
if (!buf) {
44184419
ret = -ENOMEM;
4419-
goto out6;
4420-
} else {
4421-
usb_fill_int_urb(dev->urb_intr, dev->udev,
4422-
dev->pipe_intr, buf, maxp,
4423-
intr_complete, dev, period);
4424-
dev->urb_intr->transfer_flags |= URB_FREE_BUFFER;
4420+
goto free_urbs;
44254421
}
44264422

4423+
usb_fill_int_urb(dev->urb_intr, dev->udev,
4424+
dev->pipe_intr, buf, maxp,
4425+
intr_complete, dev, period);
4426+
dev->urb_intr->transfer_flags |= URB_FREE_BUFFER;
4427+
44274428
dev->maxpacket = usb_maxpacket(dev->udev, dev->pipe_out, 1);
44284429

44294430
/* Reject broken descriptors. */
44304431
if (dev->maxpacket == 0) {
44314432
ret = -ENODEV;
4432-
goto out6;
4433+
goto free_urbs;
44334434
}
44344435

44354436
/* driver requires remote-wakeup capability during autosuspend. */
44364437
intf->needs_remote_wakeup = 1;
44374438

44384439
ret = lan78xx_phy_init(dev);
44394440
if (ret < 0)
4440-
goto out7;
4441+
goto free_urbs;
44414442

44424443
ret = register_netdev(netdev);
44434444
if (ret != 0) {
@@ -4459,10 +4460,8 @@ static int lan78xx_probe(struct usb_interface *intf,
44594460

44604461
out8:
44614462
phy_disconnect(netdev->phydev);
4462-
out7:
4463+
free_urbs:
44634464
usb_free_urb(dev->urb_intr);
4464-
out6:
4465-
kfree(buf);
44664465
out5:
44674466
lan78xx_unbind(dev, intf);
44684467
out4:

0 commit comments

Comments
 (0)