Re: [PATCH v1] net: bluetooth: add callback to exe l2cap when read_security uncompleted

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

 



On 7/7/25 9:21 AM, Shuai Zhang wrote:
> Dear all

(Please don't top-post)

It would probably help if you included the maintainers in the To/Cc
fields, so that your email can actually reach them

When using the b4 tool, you can simply run `b4 prep -c`.

Please resend this patch and add these emails:

Marcel Holtmann <marcel@xxxxxxxxxxxx>
Johan Hedberg <johan.hedberg@xxxxxxxxx>
Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx>
"David S. Miller" <davem@xxxxxxxxxxxxx>
Eric Dumazet <edumazet@xxxxxxxxxx>
Jakub Kicinski <kuba@xxxxxxxxxx>
Paolo Abeni <pabeni@xxxxxxxxxx>
Simon Horman <horms@xxxxxxxxxx>
linux-bluetooth@xxxxxxxxxxxxxxx
netdev@xxxxxxxxxxxxxxx
linux-kernel@xxxxxxxxxxxxxxx

Konrad

> 
> On 2025/6/27 11:02, Shuai Zhang wrote:
>> When the DUT receives a remote L2CAP Connection Request during the Read
>> Encryption Key Size procedure, if it fails to complete reading the
>> Encryption Key Size while processing the request, it will respond with
>> a Connection Response – Refused (security block), resulting in the
>> disconnection of the remote device.
>>
>> Use HCI_CONN_ENC_KEY_READY to determine whether
>> l2cap_connect_request is pending.
>>
>> When l2cap_connect occurs before the read_enc_key_size event, it will
>> be pending because HCI_CONN_ENC_KEY_READY has not yet been set.
>> The connection request will be processed once the read_enc_key_size
>> event completes.
>>
>> Signed-off-by: Shuai Zhang <quic_shuaz@xxxxxxxxxxx>
>> ---
>>  include/net/bluetooth/hci_core.h |  3 +++
>>  include/net/bluetooth/l2cap.h    | 10 +++++++++-
>>  net/bluetooth/hci_event.c        | 16 ++++++++++++++++
>>  net/bluetooth/l2cap_core.c       | 30 ++++++++++++++++++++++++++++++
>>  4 files changed, 58 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
>> index b47c74080..db329abbf 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -767,6 +767,8 @@ struct hci_conn {
>>  
>>  	struct bt_codec codec;
>>  
>> +	struct l2cap_pending_connect *pending_connect;
>> +
>>  	void (*connect_cfm_cb)	(struct hci_conn *conn, u8 status);
>>  	void (*security_cfm_cb)	(struct hci_conn *conn, u8 status);
>>  	void (*disconn_cfm_cb)	(struct hci_conn *conn, u8 reason);
>> @@ -970,6 +972,7 @@ enum {
>>  	HCI_CONN_CREATE_PA_SYNC,
>>  	HCI_CONN_PA_SYNC,
>>  	HCI_CONN_PA_SYNC_FAILED,
>> +	HCI_CONN_ENC_KEY_READY,
>>  };
>>  
>>  static inline bool hci_conn_ssp_enabled(struct hci_conn *conn)
>> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
>> index 4bb0eaedd..b1ccd56bd 100644
>> --- a/include/net/bluetooth/l2cap.h
>> +++ b/include/net/bluetooth/l2cap.h
>> @@ -679,6 +679,13 @@ struct l2cap_user {
>>  	void (*remove) (struct l2cap_conn *conn, struct l2cap_user *user);
>>  };
>>  
>> +struct l2cap_pending_connect {
>> +	struct l2cap_conn *conn;
>> +	struct l2cap_cmd_hdr cmd;
>> +	u8 data[sizeof(struct l2cap_conn_req)];
>> +	u8 rsp_code;
>> +};
>> +
>>  #define L2CAP_INFO_CL_MTU_REQ_SENT	0x01
>>  #define L2CAP_INFO_FEAT_MASK_REQ_SENT	0x04
>>  #define L2CAP_INFO_FEAT_MASK_REQ_DONE	0x08
>> @@ -976,5 +983,6 @@ void l2cap_conn_put(struct l2cap_conn *conn);
>>  
>>  int l2cap_register_user(struct l2cap_conn *conn, struct l2cap_user *user);
>>  void l2cap_unregister_user(struct l2cap_conn *conn, struct l2cap_user *user);
>> -
>> +void l2cap_process_pending_connect(struct l2cap_conn *conn,
>> +				   struct l2cap_cmd_hdr *cmd, u8 *data, u8 rsp_code);
>>  #endif /* __L2CAP_H */
>> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
>> index c4b87bfb4..6c992f83e 100644
>> --- a/net/bluetooth/hci_event.c
>> +++ b/net/bluetooth/hci_event.c
>> @@ -32,6 +32,7 @@
>>  #include <net/bluetooth/bluetooth.h>
>>  #include <net/bluetooth/hci_core.h>
>>  #include <net/bluetooth/mgmt.h>
>> +#include <net/bluetooth/l2cap.h>
>>  
>>  #include "hci_debugfs.h"
>>  #include "hci_codec.h"
>> @@ -766,10 +767,23 @@ static u8 hci_cc_read_enc_key_size(struct hci_dev *hdev, void *data,
>>  		/* Update the key encryption size with the connection one */
>>  		if (key_enc_size && *key_enc_size != conn->enc_key_size)
>>  			*key_enc_size = conn->enc_key_size;
>> +		set_bit(HCI_CONN_ENC_KEY_READY, &conn->flags);
>>  	}
>>  
>>  	hci_encrypt_cfm(conn, status);
>>  
>> +	/*Defer l2cap_connect here if it's triggered before key size is read.*/
>> +	if (conn->pending_connect) {
>> +		struct l2cap_pending_connect *pc = conn->pending_connect;
>> +
>> +		conn->pending_connect = NULL;
>> +
>> +		bt_dev_dbg(hdev, "Defer l2cap_connect");
>> +		l2cap_process_pending_connect(pc->conn, &pc->cmd, pc->data, pc->rsp_code);
>> +
>> +		kfree(pc);
>> +	}
>> +
>>  done:
>>  	hci_dev_unlock(hdev);
>>  
>> @@ -3396,6 +3410,8 @@ static void hci_disconn_complete_evt(struct hci_dev *hdev, void *data,
>>  	if (!conn)
>>  		goto unlock;
>>  
>> +	clear_bit(HCI_CONN_ENC_KEY_READY, &conn->flags);
>> +
>>  	if (ev->status) {
>>  		mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
>>  				       conn->dst_type, ev->status);
>> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
>> index 40daa3827..c4cb60e65 100644
>> --- a/net/bluetooth/l2cap_core.c
>> +++ b/net/bluetooth/l2cap_core.c
>> @@ -3982,6 +3982,30 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
>>  	struct l2cap_chan *chan = NULL, *pchan = NULL;
>>  	int result, status = L2CAP_CS_NO_INFO;
>>  
>> +	/* If encryption is requested, but the key size is not ready yet,
>> +	 * we need to wait for the key size to be ready before we can
>> +	 * proceed with the connection. We do this by deferring the
>> +	 * connection request until the key size is ready. This is done
>> +	 * by storing the connection request in the hcon->pending_connect
>> +	 * field. The connection request will be retried when the key size
>> +	 * is ready.
>> +	 */
>> +	if (test_bit(HCI_CONN_ENCRYPT, &conn->hcon->flags) &&
>> +	    !test_bit(HCI_CONN_ENC_KEY_READY, &conn->hcon->flags)) {
>> +		struct l2cap_pending_connect *pc;
>> +
>> +		pc = kzalloc(sizeof(*pc), GFP_KERNEL);
>> +		if (!pc)
>> +			return;
>> +		pc->conn = conn;
>> +		memcpy(&pc->cmd, cmd, sizeof(*cmd));
>> +		memcpy(pc->data, data, sizeof(struct l2cap_conn_req));
>> +		pc->rsp_code = rsp_code;
>> +		BT_DBG("store request and retried when keysize is ready");
>> +		conn->hcon->pending_connect = pc;
>> +		return;
>> +	}
>> +
>>  	u16 dcid = 0, scid = __le16_to_cpu(req->scid);
>>  	__le16 psm = req->psm;
>>  
>> @@ -4105,6 +4129,12 @@ static void l2cap_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
>>  	l2cap_chan_put(pchan);
>>  }
>>  
>> +void l2cap_process_pending_connect(struct l2cap_conn *conn, struct l2cap_cmd_hdr *cmd,
>> +				   u8 *data, u8 rsp_code)
>> +{
>> +	l2cap_connect(conn, cmd, data, rsp_code);
>> +}
>> +
>>  static int l2cap_connect_req(struct l2cap_conn *conn,
>>  			     struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data)
>>  {
> 
> Is there any update?
> 
> thanks,
> Shuai
> 




[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