@@ -189,6 +189,7 @@ static struct uctrl_driver {
int irq;
int pending;
struct uctrl_status status;
+ struct kref *refcnt;
} *global_driver;
static void uctrl_get_event_status(struct uctrl_driver *);
@@ -204,12 +205,28 @@ uctrl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return 0;
}
+static void uctrl_delete(struct kref *kref)
+{
+ struct uctrl_driver *p = container_of(kref, struct uctrl_driver, refcnt);
+
+ misc_deregister(&uctrl_dev);
+ free_irq(p->irq, p);
+ of_iounmap(&op->resource[0], p->regs, resource_size(&op->resource[0]));
+ kfree(p);
+}
+
+static int uctrl_close(struct inode *inode, struct file *file)
+{
+ kref_put(&global_driver->refcnt, uctrl_delete);
+}
+
static int
uctrl_open(struct inode *inode, struct file *file)
{
mutex_lock(&uctrl_mutex);
uctrl_get_event_status(global_driver);
uctrl_get_external_status(global_driver);
+ kref_get(&global_driver->refcnt);
mutex_unlock(&uctrl_mutex);
return 0;
}
@@ -224,6 +241,7 @@ static const struct file_operations uctrl_fops = {
.llseek = no_llseek,
.unlocked_ioctl = uctrl_ioctl,
.open = uctrl_open,
+ .release = uctrl_close,
};
static struct miscdevice uctrl_dev = {
@@ -404,10 +422,7 @@ static int uctrl_remove(struct platform_device *op)
struct uctrl_driver *p = dev_get_drvdata(&op->dev);
if (p) {
- misc_deregister(&uctrl_dev);
- free_irq(p->irq, p);
- of_iounmap(&op->resource[0], p->regs, resource_size(&op->resource[0]));
- kfree(p);
+ kref_put(&p->refcnt, uctrl_delete);
}
return 0;
}
A race condition may occur if the user physically removes the uctrl device while calling open(). This is a race condition between uctrl_open() function and the uctrl_remove() function, which may lead to Use-After-Free. Therefore, add a kref when open() uctrl driver and decrement the kref when close() and uctrl_remove() so that the race condition is not occured. ---------------CPU 0--------------------CPU 1----------------- | p = dev_get_drvdata(&op->dev); | ... | kfree(p); -- (1) uctrl_get_event_status(global _driver); — (2) Signed-off-by: Yoochan Lee <yoochan1026@gmail.com> --- drivers/sbus/char/uctrl.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)