]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Bluetooth: hci_sync: fix set_local_name race condition
authorPavel Shpakovskiy <pashpakovskii@salutedevices.com>
Fri, 22 Aug 2025 09:20:55 +0000 (12:20 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 4 Sep 2025 13:26:27 +0000 (15:26 +0200)
[ Upstream commit 6bbd0d3f0c23fc53c17409dd7476f38ae0ff0cd9 ]

Function set_name_sync() uses hdev->dev_name field to send
HCI_OP_WRITE_LOCAL_NAME command, but copying from data to hdev->dev_name
is called after mgmt cmd was queued, so it is possible that function
set_name_sync() will read old name value.

This change adds name as a parameter for function hci_update_name_sync()
to avoid race condition.

Fixes: 6f6ff38a1e14 ("Bluetooth: hci_sync: Convert MGMT_OP_SET_LOCAL_NAME")
Signed-off-by: Pavel Shpakovskiy <pashpakovskii@salutedevices.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/net/bluetooth/hci_sync.h
net/bluetooth/hci_sync.c
net/bluetooth/mgmt.c

index 3a7658d660224e43be491ed1769058e9850668af..a8b106d884d41d5ed2b61d12c5c0d0a662e6bfd7 100644 (file)
@@ -65,7 +65,7 @@ int hci_update_class_sync(struct hci_dev *hdev);
 
 int hci_update_eir_sync(struct hci_dev *hdev);
 int hci_update_class_sync(struct hci_dev *hdev);
-int hci_update_name_sync(struct hci_dev *hdev);
+int hci_update_name_sync(struct hci_dev *hdev, const u8 *name);
 int hci_write_ssp_mode_sync(struct hci_dev *hdev, u8 mode);
 
 int hci_get_random_address(struct hci_dev *hdev, bool require_privacy,
index acff47da799aac7b04a7f02eee751584422498c1..965b0f2b43a722dd3a026a166170bf64c462f86a 100644 (file)
@@ -3424,13 +3424,13 @@ int hci_update_scan_sync(struct hci_dev *hdev)
        return hci_write_scan_enable_sync(hdev, scan);
 }
 
-int hci_update_name_sync(struct hci_dev *hdev)
+int hci_update_name_sync(struct hci_dev *hdev, const u8 *name)
 {
        struct hci_cp_write_local_name cp;
 
        memset(&cp, 0, sizeof(cp));
 
-       memcpy(cp.name, hdev->dev_name, sizeof(cp.name));
+       memcpy(cp.name, name, sizeof(cp.name));
 
        return __hci_cmd_sync_status(hdev, HCI_OP_WRITE_LOCAL_NAME,
                                            sizeof(cp), &cp,
@@ -3482,7 +3482,7 @@ int hci_powered_update_sync(struct hci_dev *hdev)
                        hci_write_fast_connectable_sync(hdev, false);
                hci_update_scan_sync(hdev);
                hci_update_class_sync(hdev);
-               hci_update_name_sync(hdev);
+               hci_update_name_sync(hdev, hdev->dev_name);
                hci_update_eir_sync(hdev);
        }
 
index 919e1bae2b269466e4747134c7dbf9eb9f7a9096..27876512c63a43642cd3abf0e0e91d95b72ed617 100644 (file)
@@ -3897,8 +3897,11 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)
 
 static int set_name_sync(struct hci_dev *hdev, void *data)
 {
+       struct mgmt_pending_cmd *cmd = data;
+       struct mgmt_cp_set_local_name *cp = cmd->param;
+
        if (lmp_bredr_capable(hdev)) {
-               hci_update_name_sync(hdev);
+               hci_update_name_sync(hdev, cp->name);
                hci_update_eir_sync(hdev);
        }