]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
[media] rc-core: race condition during ir_raw_event_register()
authorSean Young <sean@mess.org>
Wed, 24 May 2017 09:24:51 +0000 (06:24 -0300)
committerMauro Carvalho Chehab <mchehab@s-opensource.com>
Sun, 4 Jun 2017 18:25:38 +0000 (15:25 -0300)
A rc device can call ir_raw_event_handle() after rc_allocate_device(),
but before rc_register_device() has completed. This is racey because
rcdev->raw is set before rcdev->raw->thread has a valid value.

Cc: stable@kernel.org
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Sean Young <sean@mess.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
drivers/media/rc/rc-ir-raw.c

index 90f66dc7c0d74dbed7cf370f652546eadc563bf8..a2fc1a1d58b0e317539a1a679e32f96c12d3b00f 100644 (file)
@@ -211,7 +211,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
  */
 void ir_raw_event_handle(struct rc_dev *dev)
 {
-       if (!dev->raw)
+       if (!dev->raw || !dev->raw->thread)
                return;
 
        wake_up_process(dev->raw->thread);
@@ -490,6 +490,7 @@ int ir_raw_event_register(struct rc_dev *dev)
 {
        int rc;
        struct ir_raw_handler *handler;
+       struct task_struct *thread;
 
        if (!dev)
                return -EINVAL;
@@ -507,13 +508,15 @@ int ir_raw_event_register(struct rc_dev *dev)
         * because the event is coming from userspace
         */
        if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
-               dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
-                                              "rc%u", dev->minor);
+               thread = kthread_run(ir_raw_event_thread, dev->raw, "rc%u",
+                                    dev->minor);
 
-               if (IS_ERR(dev->raw->thread)) {
-                       rc = PTR_ERR(dev->raw->thread);
+               if (IS_ERR(thread)) {
+                       rc = PTR_ERR(thread);
                        goto out;
                }
+
+               dev->raw->thread = thread;
        }
 
        mutex_lock(&ir_raw_handler_lock);