Skip to content

Commit 4f0835d

Browse files
seanyoungmchehab
authored andcommitted
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: [email protected] Cc: Hillf Danton <[email protected]> Cc: <[email protected]> # 4.16+ Signed-off-by: Sean Young <[email protected]> Signed-off-by: Mauro Carvalho Chehab <[email protected]>
1 parent 8a30c01 commit 4f0835d

File tree

1 file changed

+16
-16
lines changed

1 file changed

+16
-16
lines changed

drivers/media/rc/rc-main.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,25 +1601,25 @@ static void rc_dev_release(struct device *device)
16011601
kfree(dev);
16021602
}
16031603

1604-
#define ADD_HOTPLUG_VAR(fmt, val...) \
1605-
do { \
1606-
int err = add_uevent_var(env, fmt, val); \
1607-
if (err) \
1608-
return err; \
1609-
} while (0)
1610-
16111604
static int rc_dev_uevent(struct device *device, struct kobj_uevent_env *env)
16121605
{
16131606
struct rc_dev *dev = to_rc_dev(device);
1607+
int ret = 0;
16141608

1615-
if (dev->rc_map.name)
1616-
ADD_HOTPLUG_VAR("NAME=%s", dev->rc_map.name);
1617-
if (dev->driver_name)
1618-
ADD_HOTPLUG_VAR("DRV_NAME=%s", dev->driver_name);
1619-
if (dev->device_name)
1620-
ADD_HOTPLUG_VAR("DEV_NAME=%s", dev->device_name);
1609+
mutex_lock(&dev->lock);
16211610

1622-
return 0;
1611+
if (!dev->registered)
1612+
ret = -ENODEV;
1613+
if (ret == 0 && dev->rc_map.name)
1614+
ret = add_uevent_var(env, "NAME=%s", dev->rc_map.name);
1615+
if (ret == 0 && dev->driver_name)
1616+
ret = add_uevent_var(env, "DRV_NAME=%s", dev->driver_name);
1617+
if (ret == 0 && dev->device_name)
1618+
ret = add_uevent_var(env, "DEV_NAME=%s", dev->device_name);
1619+
1620+
mutex_unlock(&dev->lock);
1621+
1622+
return ret;
16231623
}
16241624

16251625
/*
@@ -2011,14 +2011,14 @@ void rc_unregister_device(struct rc_dev *dev)
20112011
del_timer_sync(&dev->timer_keyup);
20122012
del_timer_sync(&dev->timer_repeat);
20132013

2014-
rc_free_rx_device(dev);
2015-
20162014
mutex_lock(&dev->lock);
20172015
if (dev->users && dev->close)
20182016
dev->close(dev);
20192017
dev->registered = false;
20202018
mutex_unlock(&dev->lock);
20212019

2020+
rc_free_rx_device(dev);
2021+
20222022
/*
20232023
* lirc device should be freed with dev->registered = false, so
20242024
* that userspace polling will get notified.

0 commit comments

Comments
 (0)