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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'media/v4.9-4' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

Pull media fix from Mauro Carvalho Chehab:
"Fix for the firmware load logic of the tuner-xc2028 driver"

* tag 'media/v4.9-4' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media:
xc2028: Fix use-after-free bug properly

+16 -21
+16 -21
drivers/media/tuners/tuner-xc2028.c
··· 281 281 int i; 282 282 tuner_dbg("%s called\n", __func__); 283 283 284 + /* free allocated f/w string */ 285 + if (priv->fname != firmware_name) 286 + kfree(priv->fname); 287 + priv->fname = NULL; 288 + 289 + priv->state = XC2028_NO_FIRMWARE; 290 + memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); 291 + 284 292 if (!priv->firm) 285 293 return; 286 294 ··· 299 291 300 292 priv->firm = NULL; 301 293 priv->firm_size = 0; 302 - priv->state = XC2028_NO_FIRMWARE; 303 - 304 - memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); 305 294 } 306 295 307 296 static int load_all_firmwares(struct dvb_frontend *fe, ··· 889 884 return 0; 890 885 891 886 fail: 892 - priv->state = XC2028_NO_FIRMWARE; 887 + free_firmware(priv); 893 888 894 - memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); 895 889 if (retry_count < 8) { 896 890 msleep(50); 897 891 retry_count++; ··· 1336 1332 mutex_lock(&xc2028_list_mutex); 1337 1333 1338 1334 /* only perform final cleanup if this is the last instance */ 1339 - if (hybrid_tuner_report_instance_count(priv) == 1) { 1335 + if (hybrid_tuner_report_instance_count(priv) == 1) 1340 1336 free_firmware(priv); 1341 - kfree(priv->ctrl.fname); 1342 - priv->ctrl.fname = NULL; 1343 - } 1344 1337 1345 1338 if (priv) 1346 1339 hybrid_tuner_release_state(priv); ··· 1400 1399 1401 1400 /* 1402 1401 * Copy the config data. 1403 - * For the firmware name, keep a local copy of the string, 1404 - * in order to avoid troubles during device release. 1405 1402 */ 1406 - kfree(priv->ctrl.fname); 1407 - priv->ctrl.fname = NULL; 1408 1403 memcpy(&priv->ctrl, p, sizeof(priv->ctrl)); 1409 - if (p->fname) { 1410 - priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL); 1411 - if (priv->ctrl.fname == NULL) { 1412 - rc = -ENOMEM; 1413 - goto unlock; 1414 - } 1415 - } 1416 1404 1417 1405 /* 1418 1406 * If firmware name changed, frees firmware. As free_firmware will ··· 1416 1426 1417 1427 if (priv->state == XC2028_NO_FIRMWARE) { 1418 1428 if (!firmware_name[0]) 1419 - priv->fname = priv->ctrl.fname; 1429 + priv->fname = kstrdup(p->fname, GFP_KERNEL); 1420 1430 else 1421 1431 priv->fname = firmware_name; 1432 + 1433 + if (!priv->fname) { 1434 + rc = -ENOMEM; 1435 + goto unlock; 1436 + } 1422 1437 1423 1438 rc = request_firmware_nowait(THIS_MODULE, 1, 1424 1439 priv->fname,