aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcsonsino <csonsino@gmail.com>2019-06-12 17:00:52 -0400
committerMarcel Holtmann <marcel@holtmann.org>2019-07-06 09:33:06 -0400
commitc49a8682fc5d298d44e8d911f4fa14690ea9485e (patch)
treee7ac3e3bf08e21f3721293789828f1fb6ea3b886
parent302975cba1a4244d84e645773c82edbcfae1875f (diff)
Bluetooth: validate BLE connection interval updates
Problem: The Linux Bluetooth stack yields complete control over the BLE connection interval to the remote device. The Linux Bluetooth stack provides access to the BLE connection interval min and max values through /sys/kernel/debug/bluetooth/hci0/ conn_min_interval and /sys/kernel/debug/bluetooth/hci0/conn_max_interval. These values are used for initial BLE connections, but the remote device has the ability to request a connection parameter update. In the event that the remote side requests to change the connection interval, the Linux kernel currently only validates that the desired value is within the acceptable range in the Bluetooth specification (6 - 3200, corresponding to 7.5ms - 4000ms). There is currently no validation that the desired value requested by the remote device is within the min/max limits specified in the conn_min_interval/conn_max_interval configurations. This essentially leads to Linux yielding complete control over the connection interval to the remote device. The proposed patch adds a verification step to the connection parameter update mechanism, ensuring that the desired value is within the min/max bounds of the current connection. If the desired value is outside of the current connection min/max values, then the connection parameter update request is rejected and the negative response is returned to the remote device. Recall that the initial connection is established using the local conn_min_interval/conn_max_interval values, so this allows the Linux administrator to retain control over the BLE connection interval. The one downside that I see is that the current default Linux values for conn_min_interval and conn_max_interval typically correspond to 30ms and 50ms respectively. If this change were accepted, then it is feasible that some devices would no longer be able to negotiate to their desired connection interval values. This might be remedied by setting the default Linux conn_min_interval and conn_max_interval values to the widest supported range (6 - 3200 / 7.5ms - 4000ms). This could lead to the same behavior as the current implementation, where the remote device could request to change the connection interval value to any value that is permitted by the Bluetooth specification, and Linux would accept the desired value. Signed-off-by: Carey Sonsino <csonsino@gmail.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--net/bluetooth/hci_event.c5
-rw-r--r--net/bluetooth/l2cap_core.c9
2 files changed, 13 insertions, 1 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index c1d3a303d97f..cdb00c2ef242 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -5660,6 +5660,11 @@ static void hci_le_remote_conn_param_req_evt(struct hci_dev *hdev,
5660 return send_conn_param_neg_reply(hdev, handle, 5660 return send_conn_param_neg_reply(hdev, handle,
5661 HCI_ERROR_UNKNOWN_CONN_ID); 5661 HCI_ERROR_UNKNOWN_CONN_ID);
5662 5662
5663 if (min < hcon->le_conn_min_interval ||
5664 max > hcon->le_conn_max_interval)
5665 return send_conn_param_neg_reply(hdev, handle,
5666 HCI_ERROR_INVALID_LL_PARAMS);
5667
5663 if (hci_check_conn_params(min, max, latency, timeout)) 5668 if (hci_check_conn_params(min, max, latency, timeout))
5664 return send_conn_param_neg_reply(hdev, handle, 5669 return send_conn_param_neg_reply(hdev, handle,
5665 HCI_ERROR_INVALID_LL_PARAMS); 5670 HCI_ERROR_INVALID_LL_PARAMS);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 0bd80277a1e9..7068eded66c3 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5297,7 +5297,14 @@ static inline int l2cap_conn_param_update_req(struct l2cap_conn *conn,
5297 5297
5298 memset(&rsp, 0, sizeof(rsp)); 5298 memset(&rsp, 0, sizeof(rsp));
5299 5299
5300 err = hci_check_conn_params(min, max, latency, to_multiplier); 5300 if (min < hcon->le_conn_min_interval ||
5301 max > hcon->le_conn_max_interval) {
5302 BT_DBG("requested connection interval exceeds current bounds.");
5303 err = -EINVAL;
5304 } else {
5305 err = hci_check_conn_params(min, max, latency, to_multiplier);
5306 }
5307
5301 if (err) 5308 if (err)
5302 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED); 5309 rsp.result = cpu_to_le16(L2CAP_CONN_PARAM_REJECTED);
5303 else 5310 else