Commit d3f7d179 authored by Michael Bommarito's avatar Michael Bommarito Committed by Luiz Augusto von Dentz
Browse files

Bluetooth: MGMT: validate Add Extended Advertising Data length



MGMT_OP_ADD_EXT_ADV_DATA is registered as a variable-length command,
with MGMT_ADD_EXT_ADV_DATA_SIZE as the fixed header size.  The handler
then uses cp->adv_data_len and cp->scan_rsp_len to validate and copy
cp->data, but it never checks that those bytes are part of the mgmt
command payload.

A short command can therefore make add_ext_adv_data() pass an
out-of-bounds pointer into tlv_data_is_valid().  If the bytes beyond
the command buffer are addressable, they can also be copied into the
advertising instance as scan response data, where the caller can read
them back via MGMT_OP_GET_ADV_INSTANCE.  The trigger requires
CAP_NET_ADMIN in the initial user namespace; KASAN reports an 8-byte
slab-out-of-bounds read.

Reject commands whose length does not match the fixed header plus both
advertising data lengths before parsing cp->data.

Fixes: 12410572 ("Bluetooth: Break add adv into two mgmt commands")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-7
Signed-off-by: default avatarMichael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent dd1dda6b
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -9110,9 +9110,15 @@ static int add_ext_adv_data(struct sock *sk, struct hci_dev *hdev, void *data,
	struct adv_info *adv_instance;
	int err = 0;
	struct mgmt_pending_cmd *cmd;
	u16 expected_len;

	BT_DBG("%s", hdev->name);

	expected_len = struct_size(cp, data, cp->adv_data_len + cp->scan_rsp_len);
	if (expected_len != data_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);