Skip to content

Commit 2bb3687

Browse files
sjancholtmann
authored andcommitted
Bluetooth: Unify advertising instance flags check
This unifies max length and TLV validity checks. Signed-off-by: Szymon Janc <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 5e2c59e commit 2bb3687

File tree

1 file changed

+48
-37
lines changed

1 file changed

+48
-37
lines changed

net/bluetooth/mgmt.c

Lines changed: 48 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -6005,45 +6005,80 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
60056005
return err;
60066006
}
60076007

6008-
static bool tlv_data_is_valid(u32 adv_flags, u8 *data, u8 len, bool is_adv_data)
6008+
static u8 tlv_data_max_len(u32 adv_flags, bool is_adv_data)
60096009
{
60106010
u8 max_len = HCI_MAX_AD_LENGTH;
6011-
int i, cur_len;
6012-
bool flags_managed = false;
6013-
bool tx_power_managed = false;
60146011

60156012
if (is_adv_data) {
60166013
if (adv_flags & (MGMT_ADV_FLAG_DISCOV |
60176014
MGMT_ADV_FLAG_LIMITED_DISCOV |
6018-
MGMT_ADV_FLAG_MANAGED_FLAGS)) {
6019-
flags_managed = true;
6015+
MGMT_ADV_FLAG_MANAGED_FLAGS))
60206016
max_len -= 3;
6021-
}
60226017

6023-
if (adv_flags & MGMT_ADV_FLAG_TX_POWER) {
6024-
tx_power_managed = true;
6018+
if (adv_flags & MGMT_ADV_FLAG_TX_POWER)
60256019
max_len -= 3;
6026-
}
60276020
} else {
60286021
/* at least 1 byte of name should fit in */
60296022
if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME)
60306023
max_len -= 3;
60316024

6032-
if (adv_flags & MGMT_ADV_FLAG_APPEARANCE)
6025+
if (adv_flags & (MGMT_ADV_FLAG_APPEARANCE))
60336026
max_len -= 4;
60346027
}
60356028

6029+
return max_len;
6030+
}
6031+
6032+
static bool flags_managed(u32 adv_flags)
6033+
{
6034+
return adv_flags & (MGMT_ADV_FLAG_DISCOV |
6035+
MGMT_ADV_FLAG_LIMITED_DISCOV |
6036+
MGMT_ADV_FLAG_MANAGED_FLAGS);
6037+
}
6038+
6039+
static bool tx_power_managed(u32 adv_flags)
6040+
{
6041+
return adv_flags & MGMT_ADV_FLAG_TX_POWER;
6042+
}
6043+
6044+
static bool name_managed(u32 adv_flags)
6045+
{
6046+
return adv_flags & MGMT_ADV_FLAG_LOCAL_NAME;
6047+
}
6048+
6049+
static bool appearance_managed(u32 adv_flags)
6050+
{
6051+
return adv_flags & MGMT_ADV_FLAG_APPEARANCE;
6052+
}
6053+
6054+
static bool tlv_data_is_valid(u32 adv_flags, u8 *data, u8 len, bool is_adv_data)
6055+
{
6056+
int i, cur_len;
6057+
u8 max_len;
6058+
6059+
max_len = tlv_data_max_len(adv_flags, is_adv_data);
6060+
60366061
if (len > max_len)
60376062
return false;
60386063

60396064
/* Make sure that the data is correctly formatted. */
60406065
for (i = 0, cur_len = 0; i < len; i += (cur_len + 1)) {
60416066
cur_len = data[i];
60426067

6043-
if (flags_managed && data[i + 1] == EIR_FLAGS)
6068+
if (data[i + 1] == EIR_FLAGS && flags_managed(adv_flags))
6069+
return false;
6070+
6071+
if (data[i + 1] == EIR_TX_POWER && tx_power_managed(adv_flags))
6072+
return false;
6073+
6074+
if (data[i + 1] == EIR_NAME_COMPLETE && name_managed(adv_flags))
6075+
return false;
6076+
6077+
if (data[i + 1] == EIR_NAME_SHORT && name_managed(adv_flags))
60446078
return false;
60456079

6046-
if (tx_power_managed && data[i + 1] == EIR_TX_POWER)
6080+
if (data[i + 1] == EIR_APPEARANCE &&
6081+
appearance_managed(adv_flags))
60476082
return false;
60486083

60496084
/* If the current field length would exceed the total data
@@ -6351,30 +6386,6 @@ static int remove_advertising(struct sock *sk, struct hci_dev *hdev,
63516386
return err;
63526387
}
63536388

6354-
static u8 tlv_data_max_len(u32 adv_flags, bool is_adv_data)
6355-
{
6356-
u8 max_len = HCI_MAX_AD_LENGTH;
6357-
6358-
if (is_adv_data) {
6359-
if (adv_flags & (MGMT_ADV_FLAG_DISCOV |
6360-
MGMT_ADV_FLAG_LIMITED_DISCOV |
6361-
MGMT_ADV_FLAG_MANAGED_FLAGS))
6362-
max_len -= 3;
6363-
6364-
if (adv_flags & MGMT_ADV_FLAG_TX_POWER)
6365-
max_len -= 3;
6366-
} else {
6367-
/* at least 1 byte of name should fit in */
6368-
if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME)
6369-
max_len -= 3;
6370-
6371-
if (adv_flags & (MGMT_ADV_FLAG_APPEARANCE))
6372-
max_len -= 4;
6373-
}
6374-
6375-
return max_len;
6376-
}
6377-
63786389
static int get_adv_size_info(struct sock *sk, struct hci_dev *hdev,
63796390
void *data, u16 data_len)
63806391
{

0 commit comments

Comments
 (0)