@@ -6005,45 +6005,80 @@ static int read_adv_features(struct sock *sk, struct hci_dev *hdev,
6005
6005
return err ;
6006
6006
}
6007
6007
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 )
6009
6009
{
6010
6010
u8 max_len = HCI_MAX_AD_LENGTH ;
6011
- int i , cur_len ;
6012
- bool flags_managed = false;
6013
- bool tx_power_managed = false;
6014
6011
6015
6012
if (is_adv_data ) {
6016
6013
if (adv_flags & (MGMT_ADV_FLAG_DISCOV |
6017
6014
MGMT_ADV_FLAG_LIMITED_DISCOV |
6018
- MGMT_ADV_FLAG_MANAGED_FLAGS )) {
6019
- flags_managed = true;
6015
+ MGMT_ADV_FLAG_MANAGED_FLAGS ))
6020
6016
max_len -= 3 ;
6021
- }
6022
6017
6023
- if (adv_flags & MGMT_ADV_FLAG_TX_POWER ) {
6024
- tx_power_managed = true;
6018
+ if (adv_flags & MGMT_ADV_FLAG_TX_POWER )
6025
6019
max_len -= 3 ;
6026
- }
6027
6020
} else {
6028
6021
/* at least 1 byte of name should fit in */
6029
6022
if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME )
6030
6023
max_len -= 3 ;
6031
6024
6032
- if (adv_flags & MGMT_ADV_FLAG_APPEARANCE )
6025
+ if (adv_flags & ( MGMT_ADV_FLAG_APPEARANCE ) )
6033
6026
max_len -= 4 ;
6034
6027
}
6035
6028
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
+
6036
6061
if (len > max_len )
6037
6062
return false;
6038
6063
6039
6064
/* Make sure that the data is correctly formatted. */
6040
6065
for (i = 0 , cur_len = 0 ; i < len ; i += (cur_len + 1 )) {
6041
6066
cur_len = data [i ];
6042
6067
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 ))
6044
6078
return false;
6045
6079
6046
- if (tx_power_managed && data [i + 1 ] == EIR_TX_POWER )
6080
+ if (data [i + 1 ] == EIR_APPEARANCE &&
6081
+ appearance_managed (adv_flags ))
6047
6082
return false;
6048
6083
6049
6084
/* 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,
6351
6386
return err ;
6352
6387
}
6353
6388
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
-
6378
6389
static int get_adv_size_info (struct sock * sk , struct hci_dev * hdev ,
6379
6390
void * data , u16 data_len )
6380
6391
{
0 commit comments