| From foo@baz Mon Sep 17 12:33:31 CEST 2018 |
| From: Anton Vasilyev <vasilyev@ispras.ru> |
| Date: Mon, 23 Jul 2018 13:04:54 -0400 |
| Subject: media: dw2102: Fix memleak on sequence of probes |
| |
| From: Anton Vasilyev <vasilyev@ispras.ru> |
| |
| [ Upstream commit 299c7007e93645067e1d2743f4e50156de78c4ff ] |
| |
| Each call to dw2102_probe() allocates memory by kmemdup for structures |
| p1100, s660, p7500 and s421, but there is no their deallocation. |
| dvb_usb_device_init() copies the corresponding structure into |
| dvb_usb_device->props, so there is no use of original structure after |
| dvb_usb_device_init(). |
| |
| The patch moves structures from global scope to local and adds their |
| deallocation. |
| |
| Found by Linux Driver Verification project (linuxtesting.org). |
| |
| Signed-off-by: Anton Vasilyev <vasilyev@ispras.ru> |
| Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| drivers/media/usb/dvb-usb/dw2102.c | 19 ++++++++++++++----- |
| 1 file changed, 14 insertions(+), 5 deletions(-) |
| |
| --- a/drivers/media/usb/dvb-usb/dw2102.c |
| +++ b/drivers/media/usb/dvb-usb/dw2102.c |
| @@ -2103,14 +2103,12 @@ static struct dvb_usb_device_properties |
| } |
| }; |
| |
| -static struct dvb_usb_device_properties *p1100; |
| static const struct dvb_usb_device_description d1100 = { |
| "Prof 1100 USB ", |
| {&dw2102_table[PROF_1100], NULL}, |
| {NULL}, |
| }; |
| |
| -static struct dvb_usb_device_properties *s660; |
| static const struct dvb_usb_device_description d660 = { |
| "TeVii S660 USB", |
| {&dw2102_table[TEVII_S660], NULL}, |
| @@ -2129,14 +2127,12 @@ static const struct dvb_usb_device_descr |
| {NULL}, |
| }; |
| |
| -static struct dvb_usb_device_properties *p7500; |
| static const struct dvb_usb_device_description d7500 = { |
| "Prof 7500 USB DVB-S2", |
| {&dw2102_table[PROF_7500], NULL}, |
| {NULL}, |
| }; |
| |
| -static struct dvb_usb_device_properties *s421; |
| static const struct dvb_usb_device_description d421 = { |
| "TeVii S421 PCI", |
| {&dw2102_table[TEVII_S421], NULL}, |
| @@ -2336,6 +2332,11 @@ static int dw2102_probe(struct usb_inter |
| const struct usb_device_id *id) |
| { |
| int retval = -ENOMEM; |
| + struct dvb_usb_device_properties *p1100; |
| + struct dvb_usb_device_properties *s660; |
| + struct dvb_usb_device_properties *p7500; |
| + struct dvb_usb_device_properties *s421; |
| + |
| p1100 = kmemdup(&s6x0_properties, |
| sizeof(struct dvb_usb_device_properties), GFP_KERNEL); |
| if (!p1100) |
| @@ -2404,8 +2405,16 @@ static int dw2102_probe(struct usb_inter |
| 0 == dvb_usb_device_init(intf, &t220_properties, |
| THIS_MODULE, NULL, adapter_nr) || |
| 0 == dvb_usb_device_init(intf, &tt_s2_4600_properties, |
| - THIS_MODULE, NULL, adapter_nr)) |
| + THIS_MODULE, NULL, adapter_nr)) { |
| + |
| + /* clean up copied properties */ |
| + kfree(s421); |
| + kfree(p7500); |
| + kfree(s660); |
| + kfree(p1100); |
| + |
| return 0; |
| + } |
| |
| retval = -ENODEV; |
| kfree(s421); |