Commit 529d4492 authored by Luiz Augusto von Dentz's avatar Luiz Augusto von Dentz
Browse files

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
Loading
Loading
Loading
Loading
+42 −29
Original line number Diff line number Diff line
@@ -4546,6 +4546,22 @@ static int set_exp_feature(struct sock *sk, struct hci_dev *hdev,
			       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,
			    u16 data_len)
{
@@ -4577,10 +4593,10 @@ static int get_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
	} else {
		params = hci_conn_params_lookup(hdev, &cp->addr.bdaddr,
						le_addr_type(cp->addr.type));

		if (!params)
			goto done;

		supported_flags = get_params_flags(hdev, params);
		current_flags = params->flags;
	}

@@ -4648,20 +4664,23 @@ 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)",
				    &cp->addr.bdaddr, cp->addr.type);
		}
	} else {

		goto unlock;
	}

	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");
	if (!params) {
		bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
			    &cp->addr.bdaddr, le_addr_type(cp->addr.type));
		goto unlock;
	}

	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;
	}

@@ -4673,12 +4692,6 @@ static int set_device_flags(struct sock *sk, struct hci_dev *hdev, void *data,
	 */
	if (params->flags & HCI_CONN_FLAG_DEVICE_PRIVACY)
		hci_update_passive_scan(hdev);
		} else {
			bt_dev_warn(hdev, "No such LE device %pMR (0x%x)",
				    &cp->addr.bdaddr,
				    le_addr_type(cp->addr.type));
		}
	}

unlock:
	hci_dev_unlock(hdev);