diff options
author | Sean Young <sean@mess.org> | 2016-10-31 15:52:26 -0200 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@s-opensource.com> | 2016-11-21 13:19:56 -0200 |
commit | afbb110172b93e44a3fd1b5afb3a71f7f9da4406 (patch) | |
tree | 0c935be28421b6f40f6be2e2c29a9f2b7de75038 | |
parent | 12accdcb92ca997ffc3bf1e76887fb991d5ac773 (diff) |
[media] lirc: prevent use-after free
If you unplug an lirc device while reading from it, you will get an
use after free as the cdev is freed while still in use.
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
-rw-r--r-- | drivers/media/rc/lirc_dev.c | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index bb2f47a21d68..7215891da248 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c @@ -161,15 +161,15 @@ static int lirc_cdev_add(struct irctl *ir) struct lirc_driver *d = &ir->d; struct cdev *cdev; - cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); + cdev = cdev_alloc(); if (!cdev) goto err_out; if (d->fops) { - cdev_init(cdev, d->fops); + cdev->ops = d->fops; cdev->owner = d->owner; } else { - cdev_init(cdev, &lirc_dev_fops); + cdev->ops = &lirc_dev_fops; cdev->owner = THIS_MODULE; } retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); @@ -187,7 +187,7 @@ static int lirc_cdev_add(struct irctl *ir) return 0; err_out: - kfree(cdev); + cdev_del(cdev); return retval; } @@ -417,7 +417,6 @@ int lirc_unregister_driver(int minor) } else { lirc_irctl_cleanup(ir); cdev_del(cdev); - kfree(cdev); kfree(ir); irctls[minor] = NULL; } @@ -518,7 +517,6 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) lirc_irctl_cleanup(ir); cdev_del(cdev); irctls[ir->d.minor] = NULL; - kfree(cdev); kfree(ir); } |