From f0cf5a24cefeb629876bd15d668ff062c8655e28 Mon Sep 17 00:00:00 2001 From: Binbin Deng <18983559317@163.com> Date: Mon, 19 Oct 2026 19:16:11 +0800 Subject: [PATCH] Bluetooth: hci_core: Initialize IRK before publication hci_add_irk() initializes the identity address and address type of a newly allocated IRK, publishes it on hdev->identity_resolving_keys, and only then initializes its value and RPA. RCU readers such as hci_find_irk_by_rpa() and the debugfs identity_resolving_keys_show() can traverse the new entry during that window and see a zero or partially initialized IRK. The race is reachable by racing an IRK addition with another CPU resolving or dumping IRKs. In particular, userspace can issue MGMT_OP_LOAD_IRKS while another process reads the corresponding debugfs file or triggers RPA resolution. Initialize the IRK value and RPA before publishing a newly allocated IRK. Existing IRKs remain published and continue to be updated in place. Found during a static-analysis-assisted audit: candidate sites were surfaced by a Coccinelle rule, and the reader/writer paths were confirmed by LLM-assisted (GLM-5.3) code inspection. The issue was not observed at runtime; it is identified by code inspection only. Fixes: adae20cb2d20 ("Bluetooth: Convert IRK list to RCU") Assisted-by: GLM-5.3 coccinelle Signed-off-by: Binbin Deng <18983559317@163.com> Signed-off-by: Luiz Augusto von Dentz --- net/bluetooth/hci_core.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 209244fd9391..65373e4aea94 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1315,9 +1315,10 @@ struct smp_ltk *hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 val[16], bdaddr_t *rpa) { - struct smp_irk *irk; + struct smp_irk *irk, *old_irk; - irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); + old_irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type); + irk = old_irk; if (!irk) { irk = kzalloc_obj(*irk); if (!irk) @@ -1326,12 +1327,14 @@ struct smp_irk *hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, bacpy(&irk->bdaddr, bdaddr); irk->addr_type = addr_type; - list_add_rcu(&irk->list, &hdev->identity_resolving_keys); } memcpy(irk->val, val, 16); bacpy(&irk->rpa, rpa); + if (!old_irk) + list_add_rcu(&irk->list, &hdev->identity_resolving_keys); + return irk; }