Skip to content

Commit 910c996

Browse files
Wang Haijhovold
authored andcommitted
USB: serial: keyspan: fix memleak on probe errors
I got memory leak as follows when doing fault injection test: unreferenced object 0xffff888258228440 (size 64): comm "kworker/7:2", pid 2005, jiffies 4294989509 (age 824.540s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<ffffffff8167939c>] slab_post_alloc_hook+0x9c/0x490 [<ffffffff8167f627>] kmem_cache_alloc_trace+0x1f7/0x470 [<ffffffffa02ac0e4>] keyspan_port_probe+0xa4/0x5d0 [keyspan] [<ffffffffa0294c07>] usb_serial_device_probe+0x97/0x1d0 [usbserial] [<ffffffff82b50ca7>] really_probe+0x167/0x460 [<ffffffff82b51099>] __driver_probe_device+0xf9/0x180 [<ffffffff82b51173>] driver_probe_device+0x53/0x130 [<ffffffff82b516f5>] __device_attach_driver+0x105/0x130 [<ffffffff82b4cfe9>] bus_for_each_drv+0x129/0x190 [<ffffffff82b50a69>] __device_attach+0x1c9/0x270 [<ffffffff82b518d0>] device_initial_probe+0x20/0x30 [<ffffffff82b4f062>] bus_probe_device+0x142/0x160 [<ffffffff82b4a4e9>] device_add+0x829/0x1300 [<ffffffffa0295fda>] usb_serial_probe.cold+0xc9b/0x14ac [usbserial] [<ffffffffa02266aa>] usb_probe_interface+0x1aa/0x3c0 [usbcore] [<ffffffff82b50ca7>] really_probe+0x167/0x460 If keyspan_port_probe() fails to allocate memory for an out_buffer[i] or in_buffer[i], the previously allocated memory for out_buffer or in_buffer needs to be freed on the error handling path, otherwise a memory leak will result. Fixes: bad41a5 ("USB: keyspan: fix port DMA-buffer allocations") Reported-by: Hulk Robot <[email protected]> Signed-off-by: Wang Hai <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: [email protected] # 3.12 Signed-off-by: Johan Hovold <[email protected]>
1 parent f5cfbec commit 910c996

File tree

1 file changed

+7
-8
lines changed

1 file changed

+7
-8
lines changed

drivers/usb/serial/keyspan.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2890,22 +2890,22 @@ static int keyspan_port_probe(struct usb_serial_port *port)
28902890
for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i) {
28912891
p_priv->in_buffer[i] = kzalloc(IN_BUFLEN, GFP_KERNEL);
28922892
if (!p_priv->in_buffer[i])
2893-
goto err_in_buffer;
2893+
goto err_free_in_buffer;
28942894
}
28952895

28962896
for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i) {
28972897
p_priv->out_buffer[i] = kzalloc(OUT_BUFLEN, GFP_KERNEL);
28982898
if (!p_priv->out_buffer[i])
2899-
goto err_out_buffer;
2899+
goto err_free_out_buffer;
29002900
}
29012901

29022902
p_priv->inack_buffer = kzalloc(INACK_BUFLEN, GFP_KERNEL);
29032903
if (!p_priv->inack_buffer)
2904-
goto err_inack_buffer;
2904+
goto err_free_out_buffer;
29052905

29062906
p_priv->outcont_buffer = kzalloc(OUTCONT_BUFLEN, GFP_KERNEL);
29072907
if (!p_priv->outcont_buffer)
2908-
goto err_outcont_buffer;
2908+
goto err_free_inack_buffer;
29092909

29102910
p_priv->device_details = d_details;
29112911

@@ -2951,15 +2951,14 @@ static int keyspan_port_probe(struct usb_serial_port *port)
29512951

29522952
return 0;
29532953

2954-
err_outcont_buffer:
2954+
err_free_inack_buffer:
29552955
kfree(p_priv->inack_buffer);
2956-
err_inack_buffer:
2956+
err_free_out_buffer:
29572957
for (i = 0; i < ARRAY_SIZE(p_priv->out_buffer); ++i)
29582958
kfree(p_priv->out_buffer[i]);
2959-
err_out_buffer:
2959+
err_free_in_buffer:
29602960
for (i = 0; i < ARRAY_SIZE(p_priv->in_buffer); ++i)
29612961
kfree(p_priv->in_buffer[i]);
2962-
err_in_buffer:
29632962
kfree(p_priv);
29642963

29652964
return -ENOMEM;

0 commit comments

Comments
 (0)