aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-07-07 14:58:39 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-07 15:22:37 -0400
commit1c39858b5dd46004b12c5acd26d8df346bef8a10 (patch)
treec81d53cad2d1e4cd56f05c305340f9ba056fb801
parentd23cf676d0e9d1fdc066d2dcb7f8bc0e2d4c75bd (diff)
Fix use-after-free oops in Bluetooth HID.
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>
-rw-r--r--net/bluetooth/hidp/core.c18
1 files changed, 9 insertions, 9 deletions
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index ceadfcf457c1..450eb0244bbf 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -581,15 +581,6 @@ static int hidp_session(void *arg)
581 581
582 hidp_del_timer(session); 582 hidp_del_timer(session);
583 583
584 fput(session->intr_sock->file);
585
586 wait_event_timeout(*(ctrl_sk->sk_sleep),
587 (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500));
588
589 fput(session->ctrl_sock->file);
590
591 __hidp_unlink_session(session);
592
593 if (session->input) { 584 if (session->input) {
594 input_unregister_device(session->input); 585 input_unregister_device(session->input);
595 session->input = NULL; 586 session->input = NULL;
@@ -601,6 +592,15 @@ static int hidp_session(void *arg)
601 hid_free_device(session->hid); 592 hid_free_device(session->hid);
602 } 593 }
603 594
595 fput(session->intr_sock->file);
596
597 wait_event_timeout(*(ctrl_sk->sk_sleep),
598 (ctrl_sk->sk_state == BT_CLOSED), msecs_to_jiffies(500));
599
600 fput(session->ctrl_sock->file);
601
602 __hidp_unlink_session(session);
603
604 up_write(&hidp_session_sem); 604 up_write(&hidp_session_sem);
605 605
606 kfree(session); 606 kfree(session);