Commit 8d5c1b8c authored by Paolo Abeni's avatar Paolo Abeni
Browse files
Luiz Augusto von Dentz says:

====================
bluetooth pull request for net:

 - SCO: remove the redundant sco_conn_put
 - MGMT: Fix slab-use-after-free Read in set_powered_sync
 - MGMT: Fix possible deadlocks

* tag 'for-net-2024-11-26' of git://git.kernel.org/pub/scm/linux/kernel/git/bluetooth/bluetooth:
  Bluetooth: SCO: remove the redundant sco_conn_put
  Bluetooth: MGMT: Fix possible deadlocks
  Bluetooth: MGMT: Fix slab-use-after-free Read in set_powered_sync
====================

Link: https://patch.msgid.link/20241126165149.899213-1-luiz.dentz@gmail.com


Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents d1524d04 ed958855
Loading
Loading
Loading
Loading
+27 −11
Original line number Diff line number Diff line
@@ -1318,7 +1318,8 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
	struct mgmt_mode *cp;

	/* Make sure cmd still outstanding. */
	if (cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
	if (err == -ECANCELED ||
	    cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
		return;

	cp = cmd->param;
@@ -1351,7 +1352,13 @@ static void mgmt_set_powered_complete(struct hci_dev *hdev, void *data, int err)
static int set_powered_sync(struct hci_dev *hdev, void *data)
{
	struct mgmt_pending_cmd *cmd = data;
	struct mgmt_mode *cp = cmd->param;
	struct mgmt_mode *cp;

	/* Make sure cmd still outstanding. */
	if (cmd != pending_find(MGMT_OP_SET_POWERED, hdev))
		return -ECANCELED;

	cp = cmd->param;

	BT_DBG("%s", hdev->name);

@@ -1511,7 +1518,8 @@ static void mgmt_set_discoverable_complete(struct hci_dev *hdev, void *data,
	bt_dev_dbg(hdev, "err %d", err);

	/* Make sure cmd still outstanding. */
	if (cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
	if (err == -ECANCELED ||
	    cmd != pending_find(MGMT_OP_SET_DISCOVERABLE, hdev))
		return;

	hci_dev_lock(hdev);
@@ -1685,7 +1693,8 @@ static void mgmt_set_connectable_complete(struct hci_dev *hdev, void *data,
	bt_dev_dbg(hdev, "err %d", err);

	/* Make sure cmd still outstanding. */
	if (cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
	if (err == -ECANCELED ||
	    cmd != pending_find(MGMT_OP_SET_CONNECTABLE, hdev))
		return;

	hci_dev_lock(hdev);
@@ -1917,7 +1926,7 @@ static void set_ssp_complete(struct hci_dev *hdev, void *data, int err)
	bool changed;

	/* Make sure cmd still outstanding. */
	if (cmd != pending_find(MGMT_OP_SET_SSP, hdev))
	if (err == -ECANCELED || cmd != pending_find(MGMT_OP_SET_SSP, hdev))
		return;

	if (err) {
@@ -3841,7 +3850,8 @@ static void set_name_complete(struct hci_dev *hdev, void *data, int err)

	bt_dev_dbg(hdev, "err %d", err);

	if (cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
	if (err == -ECANCELED ||
	    cmd != pending_find(MGMT_OP_SET_LOCAL_NAME, hdev))
		return;

	if (status) {
@@ -4016,7 +4026,8 @@ static void set_default_phy_complete(struct hci_dev *hdev, void *data, int err)
	struct sk_buff *skb = cmd->skb;
	u8 status = mgmt_status(err);

	if (cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
	if (err == -ECANCELED ||
	    cmd != pending_find(MGMT_OP_SET_PHY_CONFIGURATION, hdev))
		return;

	if (!status) {
@@ -5907,13 +5918,16 @@ static void start_discovery_complete(struct hci_dev *hdev, void *data, int err)
{
	struct mgmt_pending_cmd *cmd = data;

	bt_dev_dbg(hdev, "err %d", err);

	if (err == -ECANCELED)
		return;

	if (cmd != pending_find(MGMT_OP_START_DISCOVERY, hdev) &&
	    cmd != pending_find(MGMT_OP_START_LIMITED_DISCOVERY, hdev) &&
	    cmd != pending_find(MGMT_OP_START_SERVICE_DISCOVERY, hdev))
		return;

	bt_dev_dbg(hdev, "err %d", err);

	mgmt_cmd_complete(cmd->sk, cmd->index, cmd->opcode, mgmt_status(err),
			  cmd->param, 1);
	mgmt_pending_remove(cmd);
@@ -6146,7 +6160,8 @@ static void stop_discovery_complete(struct hci_dev *hdev, void *data, int err)
{
	struct mgmt_pending_cmd *cmd = data;

	if (cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
	if (err == -ECANCELED ||
	    cmd != pending_find(MGMT_OP_STOP_DISCOVERY, hdev))
		return;

	bt_dev_dbg(hdev, "err %d", err);
@@ -8137,7 +8152,8 @@ static void read_local_oob_ext_data_complete(struct hci_dev *hdev, void *data,
	u8 status = mgmt_status(err);
	u16 eir_len;

	if (cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
	if (err == -ECANCELED ||
	    cmd != pending_find(MGMT_OP_READ_LOCAL_OOB_EXT_DATA, hdev))
		return;

	if (!status) {
+1 −1
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ static void sco_sock_timeout(struct work_struct *work)
	sco_conn_lock(conn);
	if (!conn->hcon) {
		sco_conn_unlock(conn);
		sco_conn_put(conn);
		return;
	}
	sk = sco_sock_hold(conn);
@@ -192,7 +193,6 @@ static struct sco_conn *sco_conn_add(struct hci_conn *hcon)
			conn->hcon = hcon;
			sco_conn_unlock(conn);
		}
		sco_conn_put(conn);
		return conn;
	}