Bluetooth: btintel: Check dsbr size from EFI variable
authorKees Cook <kees@kernel.org>
Tue, 20 May 2025 16:31:35 +0000 (09:31 -0700)
committerLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
Thu, 22 May 2025 17:06:28 +0000 (13:06 -0400)
Since the size of struct btintel_dsbr is already known, we can just
start there instead of querying the EFI variable size. If the final
result doesn't match what we expect also fail. This fixes a stack buffer
overflow when the EFI variable is larger than struct btintel_dsbr.

Reported-by: zepta <z3ptaa@gmail.com>
Closes: https://lore.kernel.org/all/CAPBS6KoaWV9=dtjTESZiU6KK__OZX0KpDk-=JEH8jCHFLUYv3Q@mail.gmail.com
Fixes: eb9e749c0182 ("Bluetooth: btintel: Allow configuring drive strength of BRI")
Signed-off-by: Kees Cook <kees@kernel.org>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
drivers/bluetooth/btintel.c

index ae92490d0c78ad61d018ae4a57e7150971c31313..55cc1652bfe4e6ac36362ea3a887d90e2c560601 100644 (file)
@@ -2719,7 +2719,7 @@ static int btintel_uefi_get_dsbr(u32 *dsbr_var)
        } __packed data;
 
        efi_status_t status;
-       unsigned long data_size = 0;
+       unsigned long data_size = sizeof(data);
        efi_guid_t guid = EFI_GUID(0xe65d8884, 0xd4af, 0x4b20, 0x8d, 0x03,
                                   0x77, 0x2e, 0xcc, 0x3d, 0xa5, 0x31);
 
@@ -2729,16 +2729,10 @@ static int btintel_uefi_get_dsbr(u32 *dsbr_var)
        if (!efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE))
                return -EOPNOTSUPP;
 
-       status = efi.get_variable(BTINTEL_EFI_DSBR, &guid, NULL, &data_size,
-                                 NULL);
-
-       if (status != EFI_BUFFER_TOO_SMALL || !data_size)
-               return -EIO;
-
        status = efi.get_variable(BTINTEL_EFI_DSBR, &guid, NULL, &data_size,
                                  &data);
 
-       if (status != EFI_SUCCESS)
+       if (status != EFI_SUCCESS || data_size != sizeof(data))
                return -ENXIO;
 
        *dsbr_var = data.dsbr;