Bluetooth: eir: Fix possible crashes on eir_create_adv_data
eir_create_adv_data may attempt to add EIR_FLAGS and EIR_TX_POWER
without checking if that would fit.
Link: https://github.com/bluez/bluez/issues/1117#issuecomment-2958244066
Fixes: 01ce70b0a2 ("Bluetooth: eir: Move EIR/Adv Data functions to its own file")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
pull/1263/head
parent
5725bc6082
commit
47c0390226
|
|
@ -242,7 +242,7 @@ u8 eir_create_per_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
|
||||||
return ad_len;
|
return ad_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
|
u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr, u8 size)
|
||||||
{
|
{
|
||||||
struct adv_info *adv = NULL;
|
struct adv_info *adv = NULL;
|
||||||
u8 ad_len = 0, flags = 0;
|
u8 ad_len = 0, flags = 0;
|
||||||
|
|
@ -286,7 +286,7 @@ u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr)
|
||||||
/* If flags would still be empty, then there is no need to
|
/* If flags would still be empty, then there is no need to
|
||||||
* include the "Flags" AD field".
|
* include the "Flags" AD field".
|
||||||
*/
|
*/
|
||||||
if (flags) {
|
if (flags && (ad_len + eir_precalc_len(1) <= size)) {
|
||||||
ptr[0] = 0x02;
|
ptr[0] = 0x02;
|
||||||
ptr[1] = EIR_FLAGS;
|
ptr[1] = EIR_FLAGS;
|
||||||
ptr[2] = flags;
|
ptr[2] = flags;
|
||||||
|
|
@ -316,7 +316,8 @@ skip_flags:
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Provide Tx Power only if we can provide a valid value for it */
|
/* Provide Tx Power only if we can provide a valid value for it */
|
||||||
if (adv_tx_power != HCI_TX_POWER_INVALID) {
|
if (adv_tx_power != HCI_TX_POWER_INVALID &&
|
||||||
|
(ad_len + eir_precalc_len(1) <= size)) {
|
||||||
ptr[0] = 0x02;
|
ptr[0] = 0x02;
|
||||||
ptr[1] = EIR_TX_POWER;
|
ptr[1] = EIR_TX_POWER;
|
||||||
ptr[2] = (u8)adv_tx_power;
|
ptr[2] = (u8)adv_tx_power;
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
void eir_create(struct hci_dev *hdev, u8 *data);
|
void eir_create(struct hci_dev *hdev, u8 *data);
|
||||||
|
|
||||||
u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
|
u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr, u8 size);
|
||||||
u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr);
|
u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr);
|
||||||
u8 eir_create_per_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
|
u8 eir_create_per_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1822,7 +1822,8 @@ static int hci_set_ext_adv_data_sync(struct hci_dev *hdev, u8 instance)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = eir_create_adv_data(hdev, instance, pdu->data);
|
len = eir_create_adv_data(hdev, instance, pdu->data,
|
||||||
|
HCI_MAX_EXT_AD_LENGTH);
|
||||||
|
|
||||||
pdu->length = len;
|
pdu->length = len;
|
||||||
pdu->handle = adv ? adv->handle : instance;
|
pdu->handle = adv ? adv->handle : instance;
|
||||||
|
|
@ -1853,7 +1854,7 @@ static int hci_set_adv_data_sync(struct hci_dev *hdev, u8 instance)
|
||||||
|
|
||||||
memset(&cp, 0, sizeof(cp));
|
memset(&cp, 0, sizeof(cp));
|
||||||
|
|
||||||
len = eir_create_adv_data(hdev, instance, cp.data);
|
len = eir_create_adv_data(hdev, instance, cp.data, sizeof(cp.data));
|
||||||
|
|
||||||
/* There's nothing to do if the data hasn't changed */
|
/* There's nothing to do if the data hasn't changed */
|
||||||
if (hdev->adv_data_len == len &&
|
if (hdev->adv_data_len == len &&
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue