The Linux Kernel Mailing List
 help / color / mirror / Atom feed
* [PATCH] Bluetooth: mgmt: validate advertising TLV envelopes before parsing
@ 2026-05-09 17:37 Zhang Cen
  0 siblings, 0 replies; only message in thread
From: Zhang Cen @ 2026-05-09 17:37 UTC (permalink / raw)
  To: Marcel Holtmann, Luiz Augusto von Dentz
  Cc: linux-bluetooth, linux-kernel, zerocling0077, Zhang Cen

tlv_data_is_valid() loads the field length from data[i] and then inspects
data[i + 1] for managed EIR types before it proves that the element still
fits inside the supplied advertising buffer.

Move the existing per-element length check ahead of the type-byte tests so
every non-empty element is proven to fit before data[i + 1] is read.

Also reject MGMT_OP_ADD_EXT_ADV_DATA commands whose declared advertising
and scan-response lengths do not match the trailing command payload.
Unlike MGMT_OP_ADD_ADVERTISING, that path did not validate the outer
envelope before slicing cp->data for tlv_data_is_valid().

Sanitizer validation reported:
BUG: KASAN: vmalloc-out-of-bounds in tlv_data_is_valid()
Read of size 1 at addr ffffc9000031a000
Call trace:
  dump_stack_lvl() (?:?)
  print_address_description() (mm/kasan/report.c:373)
  tlv_data_is_valid() (net/bluetooth/mgmt.c:8623)
  print_report() (?:?)
  srso_alias_return_thunk() (arch/x86/include/asm/nospec-branch.h:375)
  kasan_addr_to_slab() (mm/kasan/common.c:45)
  kasan_report() (?:?)
  add_advertising() (net/bluetooth/mgmt.c:8751)
  __entry_text_end() (?:?)
  __hci_dev_get() (net/bluetooth/hci_core.c:67)
  do_raw_read_unlock() (kernel/locking/spinlock_debug.c:178)
  _raw_read_unlock() (kernel/locking/spinlock.c:262)
  hci_mgmt_cmd() (net/bluetooth/hci_sock.c:1619)
  hci_sock_sendmsg() (net/bluetooth/hci_sock.c:1800)
  sock_write_iter() (net/socket.c:1234)
  reacquire_held_locks() (kernel/locking/lockdep.c:5375)
  security_file_permission() (?:?)
  vfs_write() (fs/read_write.c:668)
  __sys_bind() (net/socket.c:1947)
  ksys_write() (fs/read_write.c:729)
  rcu_is_watching() (?:?)
  do_syscall_64() (arch/x86/entry/syscall_64.c:87)
  entry_SYSCALL_64_after_hwframe() (?:?)

Signed-off-by: Zhang Cen <rollkingzzc@gmail.com>

---
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index b05bb380e5f8..827a67db4733 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -8638,6 +8638,12 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 		if (!cur_len)
 			continue;
 
+		/* If the current field length would exceed the total data
+		 * length, then it's invalid.
+		 */
+		if (i + cur_len >= len)
+			return false;
+
 		if (data[i + 1] == EIR_FLAGS &&
 		    (!is_adv_data || flags_managed(adv_flags)))
 			return false;
@@ -8654,12 +8660,6 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
 		if (data[i + 1] == EIR_APPEARANCE &&
 		    appearance_managed(adv_flags))
 			return false;
-
-		/* If the current field length would exceed the total data
-		 * length, then it's invalid.
-		 */
-		if (i + cur_len >= len)
-			return false;
 	}
 
 	return true;
@@ -9113,6 +9113,10 @@ static int add_ext_adv_data(struct sock *sk, struct hci_dev *hdev, void *data,
 
 	BT_DBG("%s", hdev->name);
 
+	if (data_len != sizeof(*cp) + cp->adv_data_len + cp->scan_rsp_len)
+		return mgmt_cmd_status(sk, hdev->id, MGMT_OP_ADD_EXT_ADV_DATA,
+				       MGMT_STATUS_INVALID_PARAMS);
+
 	hci_dev_lock(hdev);
 
 	adv_instance = hci_find_adv_instance(hdev, cp->instance);

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2026-05-09 17:37 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-09 17:37 [PATCH] Bluetooth: mgmt: validate advertising TLV envelopes before parsing Zhang Cen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox