[RFC] Bluetooth: hidp: Check for valid ACL connection

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Check for valid ACL connection before creating an hid device.
__hidp_link_session() needs session->conn but hidp_add_connection does not check
whether session->conn is set.

Signed-off-by: David Herrmann <dh.herrmann@xxxxxxxxxxxxxx>
---

I recently got several kernel panics in hidp_add_connection when creating a
bluetooth HID device. I got these panics when the device shut down *while*
trying to initiate the HID connection.
This fix aborts the HID device creation if the ACL connection is disconnected.
This fixes the problem for me but I don't know whether there is still a
race-condition between obtainig session->conn and calling hci_conn_hold_device
in __hidp_link_session().

Also I think it would make the code nicer when calling hidp_get_device() in
hidp_add_connection and hidp_setup_input/hid just retrieves the parent-device
from session->conn.

Anyway, you can find my kernel oops message here:
https://gist.github.com/1156759
As far as I got, it is caused by:
hidp_add_connection()
 -> __hidp_link_session()
  -> hci_conn_hold_device()
   -> atomic_inc()
    -> test_and_set_bit()

Regards
David

 net/bluetooth/hidp/core.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index fb68f34..baec330 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -837,6 +837,11 @@ static int hidp_setup_input(struct hidp_session *session,
 	}
 
 	input->dev.parent = hidp_get_device(session);
+	if (!input->dev.parent) {
+		input_free_device(input);
+		session->input = NULL;
+		return -ENODEV;
+	}
 
 	input->event = hidp_input_event;
 
@@ -941,6 +946,9 @@ static int hidp_setup_hid(struct hidp_session *session,
 	strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64);
 
 	hid->dev.parent = hidp_get_device(session);
+	if (!hid->dev.parent)
+		goto dev_err;
+
 	hid->ll_driver = &hidp_hid_driver;
 
 	hid->hid_get_raw_report = hidp_get_raw_report;
@@ -948,6 +956,9 @@ static int hidp_setup_hid(struct hidp_session *session,
 
 	return 0;
 
+dev_err:
+	hid_destroy_device(hid);
+	session->hid = NULL;
 fault:
 	kfree(session->rd_data);
 	session->rd_data = NULL;
-- 
1.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux