STM code takes references to the stm device and its module for the
duration of the character device's existence or the stm_source link.
Dropping these references is not well balanced everywhere, which may
lead to leaks.
This patch balances the acquisition and releasing of these two
references and annotates each site so that it's easier to verify
correctness by reading the code.
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
(cherry picked from commit
f7c81c7176c72c7899390754b4b038a64b296e4d)
stm = to_stm_device(dev);
if (!try_module_get(stm->owner)) {
stm = to_stm_device(dev);
if (!try_module_get(stm->owner)) {
+ /* matches class_find_device() above */
put_device(dev);
return NULL;
}
put_device(dev);
return NULL;
}
* @stm: stm device, previously acquired by stm_find_device()
*
* This drops the module reference and device reference taken by
* @stm: stm device, previously acquired by stm_find_device()
*
* This drops the module reference and device reference taken by
+ * stm_find_device() or stm_char_open().
*/
void stm_put_device(struct stm_device *stm)
{
*/
void stm_put_device(struct stm_device *stm)
{
return nonseekable_open(inode, file);
err_free:
return nonseekable_open(inode, file);
err_free:
+ /* matches class_find_device() above */
+ put_device(dev);
struct stm_file *stmf = file->private_data;
stm_output_free(stmf->stm, &stmf->output);
struct stm_file *stmf = file->private_data;
stm_output_free(stmf->stm, &stmf->output);
+
+ /*
+ * matches the stm_char_open()'s
+ * class_find_device() + try_module_get()
+ */
stm_put_device(stmf->stm);
kfree(stmf);
stm_put_device(stmf->stm);
kfree(stmf);
ret = stm->data->link(stm->data, stmf->output.master,
stmf->output.channel);
ret = stm->data->link(stm->data, stmf->output.master,
stmf->output.channel);
stm_output_free(stmf->stm, &stmf->output);
stm_output_free(stmf->stm, &stmf->output);
- stm_put_device(stmf->stm);
- }
+ /* matches device_initialize() above */
put_device(&stm->dev);
err_free:
kfree(stm);
put_device(&stm->dev);
err_free:
kfree(stm);
fail_free_output:
stm_output_free(stm, &src->output);
fail_free_output:
stm_output_free(stm, &src->output);
fail_detach:
mutex_lock(&stm->link_mutex);
fail_detach:
mutex_lock(&stm->link_mutex);
return -EINVAL;
err = stm_source_link_add(src, link);
return -EINVAL;
err = stm_source_link_add(src, link);
+ if (err) {
+ /* matches the stm_find_device() above */