From dcd8bcb88d2dd246ef6716819952d6ccb0cfd4de Mon Sep 17 00:00:00 2001 From: Lyle Zhu Date: Thu, 6 Mar 2025 21:30:24 +0800 Subject: [PATCH] Bluetooth: SSP: Reply a negative rsp if binding flags are mismatched If the remote is in bondable mode, but the local is in non-bondable mode, the local host shall respond to an IO capability request with a negative response. In current implementation, it does not check the bonding flags of the both sides are consistent. Fix the issue by checking the consistency of bonding flags of the both sides. If they are not consistent, send a negative IO capability response with the reason pairing not allowed. Signed-off-by: Lyle Zhu --- subsys/bluetooth/host/classic/ssp.c | 34 ++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/host/classic/ssp.c b/subsys/bluetooth/host/classic/ssp.c index 64e082a42d3..1ee29daebd7 100644 --- a/subsys/bluetooth/host/classic/ssp.c +++ b/subsys/bluetooth/host/classic/ssp.c @@ -683,14 +683,6 @@ void bt_hci_io_capa_req(struct net_buf *buf) } #endif - resp_buf = bt_hci_cmd_create(BT_HCI_OP_IO_CAPABILITY_REPLY, - sizeof(*cp)); - if (!resp_buf) { - LOG_ERR("Out of command buffers"); - bt_conn_unref(conn); - return; - } - /* * Set authentication requirements when acting as pairing initiator to * 'dedicated bond' with MITM protection set if local IO capa @@ -718,6 +710,25 @@ void bt_hci_io_capa_req(struct net_buf *buf) } } else { auth = ssp_get_auth(conn); + + /* + * Core v6.0, Vol 3, Part C, Section 4.3.1 Non-bondable mode + * When a Bluetooth device is in non-bondable mode it shall not accept a + * pairing request that results in bonding. Devices in non-bondable mode + * may accept connections that do not request or require bonding. + * + * If the peer supports bonding mode, but the local is in non-bondable + * mode, it will send a negative response with error code + * `BT_HCI_ERR_PAIRING_NOT_ALLOWED`. + */ + if (!atomic_test_bit(conn->flags, BT_CONN_BR_BONDABLE) && + (conn->br.remote_auth > BT_HCI_NO_BONDING_MITM)) { + LOG_WRN("Invalid remote bonding requirements"); + io_capa_neg_reply(&evt->bdaddr, + BT_HCI_ERR_PAIRING_NOT_ALLOWED); + bt_conn_unref(conn); + return; + } } if (!atomic_test_bit(conn->flags, BT_CONN_BR_BONDABLE)) { @@ -725,6 +736,13 @@ void bt_hci_io_capa_req(struct net_buf *buf) auth = BT_HCI_SET_NO_BONDING(auth); } + resp_buf = bt_hci_cmd_create(BT_HCI_OP_IO_CAPABILITY_REPLY, sizeof(*cp)); + if (!resp_buf) { + LOG_ERR("Out of command buffers"); + bt_conn_unref(conn); + return; + } + cp = net_buf_add(resp_buf, sizeof(*cp)); bt_addr_copy(&cp->bdaddr, &evt->bdaddr); cp->capability = get_io_capa();