summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-07-07 18:58:39 (GMT)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-07 19:22:37 (GMT)
commit1c39858b5dd46004b12c5acd26d8df346bef8a10 (patch)
treec81d53cad2d1e4cd56f05c305340f9ba056fb801 /net
parentd23cf676d0e9d1fdc066d2dcb7f8bc0e2d4c75bd (diff)
downloadlinux-fsl-qoriq-1c39858b5dd46004b12c5acd26d8df346bef8a10.tar.xz
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>
Diffstat (limited to 'net')
-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 ceadfcf..450eb02 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -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);