summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb-frontends/au8522_decoder.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-12-21 14:38:31 -0200
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>2015-12-21 17:39:32 -0200
commitaa37763fa4b2545a6d517333aacc98ad757a4ccd (patch)
tree1846e9bea2ee3a2300df348c5135944ad6eee349 /drivers/media/dvb-frontends/au8522_decoder.c
parentc77adf214ba619ad959f37fa429aa3f1045fe0cf (diff)
downloadblackbird-op-linux-aa37763fa4b2545a6d517333aacc98ad757a4ccd.tar.gz
blackbird-op-linux-aa37763fa4b2545a6d517333aacc98ad757a4ccd.zip
[media] au8522: Avoid memory leak for device config data
As reported by kmemleak: unreferenced object 0xffff880321e1da40 (size 32): comm "modprobe", pid 3309, jiffies 4295019569 (age 2359.636s) hex dump (first 32 bytes): 47 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 G............... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<ffffffff82278c8e>] kmemleak_alloc+0x4e/0xb0 [<ffffffff8153c08c>] kmem_cache_alloc_trace+0x1ec/0x280 [<ffffffffa13a896a>] au8522_probe+0x19a/0xa30 [au8522_decoder] [<ffffffff81de0032>] i2c_device_probe+0x2b2/0x490 [<ffffffff81ca7004>] driver_probe_device+0x454/0xd90 [<ffffffff81ca7c1b>] __device_attach_driver+0x17b/0x230 [<ffffffff81ca15da>] bus_for_each_drv+0x11a/0x1b0 [<ffffffff81ca6a4d>] __device_attach+0x1cd/0x2c0 [<ffffffff81ca7d43>] device_initial_probe+0x13/0x20 [<ffffffff81ca451f>] bus_probe_device+0x1af/0x250 [<ffffffff81c9e0f3>] device_add+0x943/0x13b0 [<ffffffff81c9eb7a>] device_register+0x1a/0x20 [<ffffffff81de8626>] i2c_new_device+0x5d6/0x8f0 [<ffffffffa0d88ea4>] v4l2_i2c_new_subdev_board+0x1e4/0x250 [v4l2_common] [<ffffffffa0d88fe7>] v4l2_i2c_new_subdev+0xd7/0x110 [v4l2_common] [<ffffffffa13b2f76>] au0828_card_analog_fe_setup+0x2e6/0x3f0 [au0828] Checking where the error happens: (gdb) list *au8522_probe+0x19a 0x99a is in au8522_probe (drivers/media/dvb-frontends/au8522_decoder.c:761). 756 printk(KERN_INFO "au8522_decoder attach existing instance.\n"); 757 break; 758 } 759 760 demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL); 761 if (demod_config == NULL) { 762 if (instance == 1) 763 kfree(state); 764 return -ENOMEM; 765 } Shows that the error path is not being handled properly. The are actually several issues here: 1) config free should have been calling hybrid_tuner_release_state() function, by calling au8522_release_state(); 2) config is only allocated at the digital part. On the analog one, it is received from the caller. A complex logic could be added to address it, however, it is simpler to just embeed config inside the state. Signed-off-by: Mauro Carvalho Chehab <mchehab@osg.samsung.com>
Diffstat (limited to 'drivers/media/dvb-frontends/au8522_decoder.c')
-rw-r--r--drivers/media/dvb-frontends/au8522_decoder.c14
1 files changed, 2 insertions, 12 deletions
diff --git a/drivers/media/dvb-frontends/au8522_decoder.c b/drivers/media/dvb-frontends/au8522_decoder.c
index 28d7dc2fee34..c8f13d8370e5 100644
--- a/drivers/media/dvb-frontends/au8522_decoder.c
+++ b/drivers/media/dvb-frontends/au8522_decoder.c
@@ -730,7 +730,6 @@ static int au8522_probe(struct i2c_client *client,
struct v4l2_ctrl_handler *hdl;
struct v4l2_subdev *sd;
int instance;
- struct au8522_config *demod_config;
/* Check if the adapter supports the needed features */
if (!i2c_check_functionality(client->adapter,
@@ -754,15 +753,7 @@ static int au8522_probe(struct i2c_client *client,
break;
}
- demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
- if (demod_config == NULL) {
- if (instance == 1)
- kfree(state);
- return -ENOMEM;
- }
- demod_config->demod_address = 0x8e >> 1;
-
- state->config = demod_config;
+ state->config.demod_address = 0x8e >> 1;
state->i2c = client->adapter;
sd = &state->sd;
@@ -784,8 +775,7 @@ static int au8522_probe(struct i2c_client *client,
int err = hdl->error;
v4l2_ctrl_handler_free(hdl);
- kfree(demod_config);
- kfree(state);
+ au8522_release_state(state);
return err;
}
OpenPOWER on IntegriCloud