forked from Minki/linux
media fixes for v4.9-rc7
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJYOBAqAAoJEAhfPr2O5OEVJucQAJ9EGPFnupRUCQxqM0OGafSL /MY7cB18TLtRPVjJRNCm0aN9Y9di7iQGW+KxeWVA1S3DYeIi4AR1xaBkR5QUl9Vy +vOujTe37zwahMIyCCZYjZN4lEU6G2HjFebNplnBBTM4lPnYmKck/c+5eq9/W+yS BIb3tGI/wQ6247ku9NjmBzwz3Ekv0NKOp7uluPoiJ0EpRq2nDBaQByYjtzMlh8kh hzhffEs3l1MabaOefDwl6wVZii2LjzRP2sOwdfGS+c52/Bo3zbwD0TwC117weYLV BVymgIiWbxX3PhxjliZdsjxCUGkHvwrjS1kWVjYe6jclagZvwOyuALdRmjvS8g7p ps7AMDLV6GuUhmfo00Mcr2FXInx+DhIjPqFx85U1YckY7YhAAv8mLPbCt0Y8Ewcm 80afrZw4m2nYpM5NlUNl6CzyqOgZsOjwIoYqhi5hBspSYnQ9GOg2VEtHLdYjvnhp 25qbM+ZuO1WM/l1xBf1LT3wMSD0EObaP7dl+GimO+Nc7Qwqnt9WL6JB1xWUdwvWG l6EYmuMwFdq4V5usWVlwTTOUgva98KqpK6qIm85DUhM5CoqMPdOmn9dY/cWu27ck xUOnKP3IRmVkAKK3H+YJvggDWhz0uOI1ylQSCYKKLBwzMeVoWfW7xwIuJVu6m6P+ 8jrHSXNlD8Mu674Uc+2l =oseK -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
ea9ea6c6f5
@ -281,6 +281,14 @@ static void free_firmware(struct xc2028_data *priv)
|
||||
int i;
|
||||
tuner_dbg("%s called\n", __func__);
|
||||
|
||||
/* free allocated f/w string */
|
||||
if (priv->fname != firmware_name)
|
||||
kfree(priv->fname);
|
||||
priv->fname = NULL;
|
||||
|
||||
priv->state = XC2028_NO_FIRMWARE;
|
||||
memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
|
||||
|
||||
if (!priv->firm)
|
||||
return;
|
||||
|
||||
@ -291,9 +299,6 @@ static void free_firmware(struct xc2028_data *priv)
|
||||
|
||||
priv->firm = NULL;
|
||||
priv->firm_size = 0;
|
||||
priv->state = XC2028_NO_FIRMWARE;
|
||||
|
||||
memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
|
||||
}
|
||||
|
||||
static int load_all_firmwares(struct dvb_frontend *fe,
|
||||
@ -884,9 +889,8 @@ read_not_reliable:
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
priv->state = XC2028_NO_FIRMWARE;
|
||||
free_firmware(priv);
|
||||
|
||||
memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
|
||||
if (retry_count < 8) {
|
||||
msleep(50);
|
||||
retry_count++;
|
||||
@ -1332,11 +1336,8 @@ static int xc2028_dvb_release(struct dvb_frontend *fe)
|
||||
mutex_lock(&xc2028_list_mutex);
|
||||
|
||||
/* only perform final cleanup if this is the last instance */
|
||||
if (hybrid_tuner_report_instance_count(priv) == 1) {
|
||||
if (hybrid_tuner_report_instance_count(priv) == 1)
|
||||
free_firmware(priv);
|
||||
kfree(priv->ctrl.fname);
|
||||
priv->ctrl.fname = NULL;
|
||||
}
|
||||
|
||||
if (priv)
|
||||
hybrid_tuner_release_state(priv);
|
||||
@ -1399,19 +1400,8 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
|
||||
|
||||
/*
|
||||
* Copy the config data.
|
||||
* For the firmware name, keep a local copy of the string,
|
||||
* in order to avoid troubles during device release.
|
||||
*/
|
||||
kfree(priv->ctrl.fname);
|
||||
priv->ctrl.fname = NULL;
|
||||
memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
|
||||
if (p->fname) {
|
||||
priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
|
||||
if (priv->ctrl.fname == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If firmware name changed, frees firmware. As free_firmware will
|
||||
@ -1426,10 +1416,15 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
|
||||
|
||||
if (priv->state == XC2028_NO_FIRMWARE) {
|
||||
if (!firmware_name[0])
|
||||
priv->fname = priv->ctrl.fname;
|
||||
priv->fname = kstrdup(p->fname, GFP_KERNEL);
|
||||
else
|
||||
priv->fname = firmware_name;
|
||||
|
||||
if (!priv->fname) {
|
||||
rc = -ENOMEM;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
rc = request_firmware_nowait(THIS_MODULE, 1,
|
||||
priv->fname,
|
||||
priv->i2c_props.adap->dev.parent,
|
||||
|
Loading…
Reference in New Issue
Block a user