Bluetooth: MGMT: Fix Get Device Flags

Get Device Flags don't check if device does actually use an RPA in which
case it shall only set HCI_CONN_FLAG_REMOTE_WAKEUP if LL Privacy is
enabled.
Signed-off-by: default avatarLuiz Augusto von Dentz <luiz.von.dentz@intel.com>
parent fc5ae5b4
...@@ -4546,6 +4546,22 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev, ...@@ -4546,6 +4546,22 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
MGMT_STATUS_NOT_SUPPORTED); MGMT_STATUS_NOT_SUPPORTED);
} }
static u32 get_params_flags(struct hci_dev *hdev,
struct hci_conn_params *params)
{
u32 flags = hdev->conn_flags;
/* Devices using RPAs can only be programmed in the acceptlist if
* LL Privacy has been enable otherwise they cannot mark
* HCI_CONN_FLAG_REMOTE_WAKEUP.
*/
if ((flags & HCI_CONN_FLAG_REMOTE_WAKEUP) && !use_ll_privacy(hdev) &&
hci_find_irk_by_addr(hdev, &params->addr, params->addr_type))
flags &= ~HCI_CONN_FLAG_REMOTE_WAKEUP;
return flags;
}
static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
u16 data_len) u16 data_len)
{ {
...@@ -4577,10 +4593,10 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -4577,10 +4593,10 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
} else { } else {
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr, params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
le_addr_type(cp->addr.type)); le_addr_type(cp->addr.type));
if (!params) if (!params)
goto done; goto done;
supported_flags = get_params_flags(hdev, params);
current_flags = params->flags; current_flags = params->flags;
} }
...@@ -4648,38 +4664,35 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data, ...@@ -4648,38 +4664,35 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)", bt_dev_warn(hdev, "No such BR/EDR device %pMR (0x%x)",
&cp->addr.bdaddr, cp->addr.type); &cp->addr.bdaddr, cp->addr.type);
} }
} else {
params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
le_addr_type(cp->addr.type));
if (params) {
/* Devices using RPAs can only be programmed in the
* acceptlist LL Privacy has been enable otherwise they
* cannot mark HCI_CONN_FLAG_REMOTE_WAKEUP.
*/
if ((current_flags & HCI_CONN_FLAG_REMOTE_WAKEUP) &&
!use_ll_privacy(hdev) &&
hci_find_irk_by_addr(hdev, &params->addr,
params->addr_type)) {
bt_dev_warn(hdev,
"Cannot set wakeable for RPA");
goto unlock;
}
params->flags = current_flags; goto unlock;
status = MGMT_STATUS_SUCCESS; }
/* Update passive scan if HCI_CONN_FLAG_DEVICE_PRIVACY params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
* has been set. le_addr_type(cp->addr.type));
*/ if (!params) {
if (params->flags & HCI_CONN_FLAG_DEVICE_PRIVACY) bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
hci_update_passive_scan(hdev); &cp->addr.bdaddr, le_addr_type(cp->addr.type));
} else { goto unlock;
bt_dev_warn(hdev, "No such LE device %pMR (0x%x)", }
&cp->addr.bdaddr,
le_addr_type(cp->addr.type)); supported_flags = get_params_flags(hdev, params);
}
if ((supported_flags | current_flags) != supported_flags) {
bt_dev_warn(hdev, "Bad flag given (0x%x) vs supported (0x%0x)",
current_flags, supported_flags);
goto unlock;
} }
params->flags = current_flags;
status = MGMT_STATUS_SUCCESS;
/* Update passive scan if HCI_CONN_FLAG_DEVICE_PRIVACY
* has been set.
*/
if (params->flags & HCI_CONN_FLAG_DEVICE_PRIVACY)
hci_update_passive_scan(hdev);
unlock: unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment