aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/usb/cx231xx
diff options
context:
space:
mode:
authorAlexey Khoroshilov <khoroshilov@ispras.ru>2013-10-07 17:06:04 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2013-10-17 05:05:28 -0400
commit256d013a9bcc9a39b2e4b34ab19219bd054cf270 (patch)
treeb16380050dbe612e9c3a60e9f5bd5d6b006faaaf /drivers/media/usb/cx231xx
parent1f61d41585f8a7a52d67fd3d6aa4aa6db75f360c (diff)
[media] cx231xx: fix double free and leaks on failure path in cx231xx_usb_probe()
There are numerous issues in error handling code of cx231xx initialization. Double free (when cx231xx_init_dev() calls kfree(dev) via cx231xx_release_resources() and then cx231xx_usb_probe() does the same) and memory leaks (e.g. usb_get_dev() before (ifnum != 1) check in cx231xx_usb_probe()) are just a few of them. The patch fixes the issues in cx231xx_usb_probe() and cx231xx_init_dev() by moving usb_get_dev(interface_to_usbdev(interface)) below in code and implementing proper error handling. Found by Linux Driver Verification project (linuxtesting.org). Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
Diffstat (limited to 'drivers/media/usb/cx231xx')
-rw-r--r--drivers/media/usb/cx231xx/cx231xx-cards.c110
1 files changed, 57 insertions, 53 deletions
diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
index a384f80f595e..e9d017bea377 100644
--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
+++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
@@ -978,7 +978,6 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
978 int minor) 978 int minor)
979{ 979{
980 int retval = -ENOMEM; 980 int retval = -ENOMEM;
981 int errCode;
982 unsigned int maxh, maxw; 981 unsigned int maxh, maxw;
983 982
984 dev->udev = udev; 983 dev->udev = udev;
@@ -1014,8 +1013,8 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
1014 /* Cx231xx pre card setup */ 1013 /* Cx231xx pre card setup */
1015 cx231xx_pre_card_setup(dev); 1014 cx231xx_pre_card_setup(dev);
1016 1015
1017 errCode = cx231xx_config(dev); 1016 retval = cx231xx_config(dev);
1018 if (errCode) { 1017 if (retval) {
1019 cx231xx_errdev("error configuring device\n"); 1018 cx231xx_errdev("error configuring device\n");
1020 return -ENOMEM; 1019 return -ENOMEM;
1021 } 1020 }
@@ -1024,12 +1023,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
1024 dev->norm = dev->board.norm; 1023 dev->norm = dev->board.norm;
1025 1024
1026 /* register i2c bus */ 1025 /* register i2c bus */
1027 errCode = cx231xx_dev_init(dev); 1026 retval = cx231xx_dev_init(dev);
1028 if (errCode < 0) { 1027 if (retval) {
1029 cx231xx_dev_uninit(dev);
1030 cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n", 1028 cx231xx_errdev("%s: cx231xx_i2c_register - errCode [%d]!\n",
1031 __func__, errCode); 1029 __func__, retval);
1032 return errCode; 1030 goto err_dev_init;
1033 } 1031 }
1034 1032
1035 /* Do board specific init */ 1033 /* Do board specific init */
@@ -1047,11 +1045,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
1047 dev->interlaced = 0; 1045 dev->interlaced = 0;
1048 dev->video_input = 0; 1046 dev->video_input = 0;
1049 1047
1050 errCode = cx231xx_config(dev); 1048 retval = cx231xx_config(dev);
1051 if (errCode < 0) { 1049 if (retval) {
1052 cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n", 1050 cx231xx_errdev("%s: cx231xx_config - errCode [%d]!\n",
1053 __func__, errCode); 1051 __func__, retval);
1054 return errCode; 1052 goto err_dev_init;
1055 } 1053 }
1056 1054
1057 /* init video dma queues */ 1055 /* init video dma queues */
@@ -1075,9 +1073,9 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
1075 } 1073 }
1076 1074
1077 retval = cx231xx_register_analog_devices(dev); 1075 retval = cx231xx_register_analog_devices(dev);
1078 if (retval < 0) { 1076 if (retval) {
1079 cx231xx_release_resources(dev); 1077 cx231xx_release_analog_resources(dev);
1080 return retval; 1078 goto err_analog;
1081 } 1079 }
1082 1080
1083 cx231xx_ir_init(dev); 1081 cx231xx_ir_init(dev);
@@ -1085,6 +1083,11 @@ static int cx231xx_init_dev(struct cx231xx *dev, struct usb_device *udev,
1085 cx231xx_init_extension(dev); 1083 cx231xx_init_extension(dev);
1086 1084
1087 return 0; 1085 return 0;
1086err_analog:
1087 cx231xx_remove_from_devlist(dev);
1088err_dev_init:
1089 cx231xx_dev_uninit(dev);
1090 return retval;
1088} 1091}
1089 1092
1090#if defined(CONFIG_MODULES) && defined(MODULE) 1093#if defined(CONFIG_MODULES) && defined(MODULE)
@@ -1132,7 +1135,6 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1132 char *speed; 1135 char *speed;
1133 struct usb_interface_assoc_descriptor *assoc_desc; 1136 struct usb_interface_assoc_descriptor *assoc_desc;
1134 1137
1135 udev = usb_get_dev(interface_to_usbdev(interface));
1136 ifnum = interface->altsetting[0].desc.bInterfaceNumber; 1138 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
1137 1139
1138 /* 1140 /*
@@ -1161,6 +1163,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1161 return -ENOMEM; 1163 return -ENOMEM;
1162 } 1164 }
1163 1165
1166 udev = usb_get_dev(interface_to_usbdev(interface));
1167
1164 snprintf(dev->name, 29, "cx231xx #%d", nr); 1168 snprintf(dev->name, 29, "cx231xx #%d", nr);
1165 dev->devno = nr; 1169 dev->devno = nr;
1166 dev->model = id->driver_info; 1170 dev->model = id->driver_info;
@@ -1223,10 +1227,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1223 if (assoc_desc->bFirstInterface != ifnum) { 1227 if (assoc_desc->bFirstInterface != ifnum) {
1224 cx231xx_err(DRIVER_NAME ": Not found " 1228 cx231xx_err(DRIVER_NAME ": Not found "
1225 "matching IAD interface\n"); 1229 "matching IAD interface\n");
1226 clear_bit(dev->devno, &cx231xx_devused); 1230 retval = -ENODEV;
1227 kfree(dev); 1231 goto err_if;
1228 dev = NULL;
1229 return -ENODEV;
1230 } 1232 }
1231 1233
1232 cx231xx_info("registering interface %d\n", ifnum); 1234 cx231xx_info("registering interface %d\n", ifnum);
@@ -1242,22 +1244,13 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1242 retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); 1244 retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
1243 if (retval) { 1245 if (retval) {
1244 cx231xx_errdev("v4l2_device_register failed\n"); 1246 cx231xx_errdev("v4l2_device_register failed\n");
1245 clear_bit(dev->devno, &cx231xx_devused); 1247 retval = -EIO;
1246 kfree(dev); 1248 goto err_v4l2;
1247 dev = NULL;
1248 return -EIO;
1249 } 1249 }
1250 /* allocate device struct */ 1250 /* allocate device struct */
1251 retval = cx231xx_init_dev(dev, udev, nr); 1251 retval = cx231xx_init_dev(dev, udev, nr);
1252 if (retval) { 1252 if (retval)
1253 clear_bit(dev->devno, &cx231xx_devused); 1253 goto err_init;
1254 v4l2_device_unregister(&dev->v4l2_dev);
1255 kfree(dev);
1256 dev = NULL;
1257 usb_set_intfdata(interface, NULL);
1258
1259 return retval;
1260 }
1261 1254
1262 /* compute alternate max packet sizes for video */ 1255 /* compute alternate max packet sizes for video */
1263 uif = udev->actconfig->interface[dev->current_pcb_config. 1256 uif = udev->actconfig->interface[dev->current_pcb_config.
@@ -1275,11 +1268,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1275 1268
1276 if (dev->video_mode.alt_max_pkt_size == NULL) { 1269 if (dev->video_mode.alt_max_pkt_size == NULL) {
1277 cx231xx_errdev("out of memory!\n"); 1270 cx231xx_errdev("out of memory!\n");
1278 clear_bit(dev->devno, &cx231xx_devused); 1271 retval = -ENOMEM;
1279 v4l2_device_unregister(&dev->v4l2_dev); 1272 goto err_video_alt;
1280 kfree(dev);
1281 dev = NULL;
1282 return -ENOMEM;
1283 } 1273 }
1284 1274
1285 for (i = 0; i < dev->video_mode.num_alt; i++) { 1275 for (i = 0; i < dev->video_mode.num_alt; i++) {
@@ -1309,11 +1299,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1309 1299
1310 if (dev->vbi_mode.alt_max_pkt_size == NULL) { 1300 if (dev->vbi_mode.alt_max_pkt_size == NULL) {
1311 cx231xx_errdev("out of memory!\n"); 1301 cx231xx_errdev("out of memory!\n");
1312 clear_bit(dev->devno, &cx231xx_devused); 1302 retval = -ENOMEM;
1313 v4l2_device_unregister(&dev->v4l2_dev); 1303 goto err_vbi_alt;
1314 kfree(dev);
1315 dev = NULL;
1316 return -ENOMEM;
1317 } 1304 }
1318 1305
1319 for (i = 0; i < dev->vbi_mode.num_alt; i++) { 1306 for (i = 0; i < dev->vbi_mode.num_alt; i++) {
@@ -1344,11 +1331,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1344 1331
1345 if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) { 1332 if (dev->sliced_cc_mode.alt_max_pkt_size == NULL) {
1346 cx231xx_errdev("out of memory!\n"); 1333 cx231xx_errdev("out of memory!\n");
1347 clear_bit(dev->devno, &cx231xx_devused); 1334 retval = -ENOMEM;
1348 v4l2_device_unregister(&dev->v4l2_dev); 1335 goto err_sliced_cc_alt;
1349 kfree(dev);
1350 dev = NULL;
1351 return -ENOMEM;
1352 } 1336 }
1353 1337
1354 for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) { 1338 for (i = 0; i < dev->sliced_cc_mode.num_alt; i++) {
@@ -1380,11 +1364,8 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1380 1364
1381 if (dev->ts1_mode.alt_max_pkt_size == NULL) { 1365 if (dev->ts1_mode.alt_max_pkt_size == NULL) {
1382 cx231xx_errdev("out of memory!\n"); 1366 cx231xx_errdev("out of memory!\n");
1383 clear_bit(dev->devno, &cx231xx_devused); 1367 retval = -ENOMEM;
1384 v4l2_device_unregister(&dev->v4l2_dev); 1368 goto err_ts1_alt;
1385 kfree(dev);
1386 dev = NULL;
1387 return -ENOMEM;
1388 } 1369 }
1389 1370
1390 for (i = 0; i < dev->ts1_mode.num_alt; i++) { 1371 for (i = 0; i < dev->ts1_mode.num_alt; i++) {
@@ -1411,6 +1392,29 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
1411 request_modules(dev); 1392 request_modules(dev);
1412 1393
1413 return 0; 1394 return 0;
1395err_ts1_alt:
1396 kfree(dev->sliced_cc_mode.alt_max_pkt_size);
1397err_sliced_cc_alt:
1398 kfree(dev->vbi_mode.alt_max_pkt_size);
1399err_vbi_alt:
1400 kfree(dev->video_mode.alt_max_pkt_size);
1401err_video_alt:
1402 /* cx231xx_uninit_dev: */
1403 cx231xx_close_extension(dev);
1404 cx231xx_ir_exit(dev);
1405 cx231xx_release_analog_resources(dev);
1406 cx231xx_417_unregister(dev);
1407 cx231xx_remove_from_devlist(dev);
1408 cx231xx_dev_uninit(dev);
1409err_init:
1410 v4l2_device_unregister(&dev->v4l2_dev);
1411err_v4l2:
1412 usb_set_intfdata(interface, NULL);
1413err_if:
1414 usb_put_dev(udev);
1415 kfree(dev);
1416 clear_bit(dev->devno, &cx231xx_devused);
1417 return retval;
1414} 1418}
1415 1419
1416/* 1420/*