mirror of https://gitee.com/openkylin/linux.git
media: rc: uevent sysfs file races with rc_unregister_device()
Only report uevent file contents if device still registered, else we might read freed memory. Reported-by: syzbot+ceef16277388d6f24898@syzkaller.appspotmail.com Cc: Hillf Danton <hdanton@sina.com> Cc: <stable@vger.kernel.org> # 4.16+ Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
This commit is contained in:
parent
8a30c017c9
commit
4f0835d667
|
@ -1601,25 +1601,25 @@ static void rc_dev_release(struct device *device)
|
||||||
kfree(dev);
|
kfree(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ADD_HOTPLUG_VAR(fmt, val...) \
|
|
||||||
do { \
|
|
||||||
int err = add_uevent_var(env, fmt, val); \
|
|
||||||
if (err) \
|
|
||||||
return err; \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
|
static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
|
||||||
{
|
{
|
||||||
struct rc_dev *dev = to_rc_dev(device);
|
struct rc_dev *dev = to_rc_dev(device);
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
if (dev->rc_map.name)
|
mutex_lock(&dev->lock);
|
||||||
ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name);
|
|
||||||
if (dev->driver_name)
|
|
||||||
ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name);
|
|
||||||
if (dev->device_name)
|
|
||||||
ADD_HOTPLUG_VAR("DEV_NAME=%s", dev->device_name);
|
|
||||||
|
|
||||||
return 0;
|
if (!dev->registered)
|
||||||
|
ret = -ENODEV;
|
||||||
|
if (ret == 0 && dev->rc_map.name)
|
||||||
|
ret = add_uevent_var(env, "NAME=%s", dev->rc_map.name);
|
||||||
|
if (ret == 0 && dev->driver_name)
|
||||||
|
ret = add_uevent_var(env, "DRV_NAME=%s", dev->driver_name);
|
||||||
|
if (ret == 0 && dev->device_name)
|
||||||
|
ret = add_uevent_var(env, "DEV_NAME=%s", dev->device_name);
|
||||||
|
|
||||||
|
mutex_unlock(&dev->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2011,14 +2011,14 @@ void rc_unregister_device(struct rc_dev *dev)
|
||||||
del_timer_sync(&dev->timer_keyup);
|
del_timer_sync(&dev->timer_keyup);
|
||||||
del_timer_sync(&dev->timer_repeat);
|
del_timer_sync(&dev->timer_repeat);
|
||||||
|
|
||||||
rc_free_rx_device(dev);
|
|
||||||
|
|
||||||
mutex_lock(&dev->lock);
|
mutex_lock(&dev->lock);
|
||||||
if (dev->users && dev->close)
|
if (dev->users && dev->close)
|
||||||
dev->close(dev);
|
dev->close(dev);
|
||||||
dev->registered = false;
|
dev->registered = false;
|
||||||
mutex_unlock(&dev->lock);
|
mutex_unlock(&dev->lock);
|
||||||
|
|
||||||
|
rc_free_rx_device(dev);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lirc device should be freed with dev->registered = false, so
|
* lirc device should be freed with dev->registered = false, so
|
||||||
* that userspace polling will get notified.
|
* that userspace polling will get notified.
|
||||||
|
|
Loading…
Reference in New Issue