Fix use-after-free oops in Bluetooth HID.
authorDavid Woodhouse <dwmw2@infradead.org>
Sat, 7 Jul 2007 18:58:39 +0000 (14:58 -0400)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Sat, 7 Jul 2007 19:22:37 +0000 (12:22 -0700)
When cleaning up HIDP sessions, we currently close the ACL connection
before deregistering the input device. Closing the ACL connection
schedules a workqueue to remove the associated objects from sysfs, but
the input device still refers to them -- and if the workqueue happens to
run before the input device removal, the kernel will oops when trying to
look up PHYSDEVPATH for the removed input device.

Fix this by deregistering the input device before closing the
connections.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
net/bluetooth/hidp/core.c

index ceadfcf457c1d6346cf839cf0922d1d57f2a5e91..450eb0244bbf6080b24142b4c9686bce948cf2fe 100644 (file)
@@ -581,15 +581,6 @@ static int hidp_session(void *arg)
 
        hidp_del_timer(session);
 
-       fput(session->intr_sock->file);
-
-       wait_event_timeout(*(ctrl_sk->sk_sleep),
-               (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500));
-
-       fput(session->ctrl_sock->file);
-
-       __hidp_unlink_session(session);
-
        if (session->input) {
                input_unregister_device(session->input);
                session->input = NULL;
@@ -601,6 +592,15 @@ static int hidp_session(void *arg)
                hid_free_device(session->hid);
        }
 
+       fput(session->intr_sock->file);
+
+       wait_event_timeout(*(ctrl_sk->sk_sleep),
+               (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500));
+
+       fput(session->ctrl_sock->file);
+
+       __hidp_unlink_session(session);
+
        up_write(&hidp_session_sem);
 
        kfree(session);