DragonFlyBSD Kernel Audit
DF-1713 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/misc/evdev/cdev.c b/sys/dev/misc/evdev/cdev.c
--- a/sys/dev/misc/evdev/cdev.c
+++ b/sys/dev/misc/evdev/cdev.c
@@ -348,7 +348,7 @@
 	cdev_t dev = ap->a_head.a_dev;
 	u_long cmd = ap->a_cmd;
 	caddr_t data = ap->a_data;
-	struct evdev_dev *evdev = dev->si_drv1;
+	struct evdev_dev *evdev;
 	struct evdev_client *client;
 	struct input_keymap_entry *ke;
 	int ret, len, limit, type_num;
@@ -359,6 +359,9 @@
 	if (ret != 0)
 		return (ret);
 
+	/* Use the client's stable evdev pointer instead of dev->si_drv1, which
+	 * is set to NULL by evdev_unregister() racing with this ioctl. */
+	evdev = client->ec_evdev;
 	if (client->ec_revoked || evdev == NULL)
 		return (ENODEV);