Unverified Commit a632ad99 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!10579 Fix CVE-2024-41062

Merge Pull Request from: @ci-robot 
 
PR sync from: Zhengchao Shao <shaozhengchao@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/6AVIZD6K2GFFSYOT2CHLMLVWDMF7UGAO/ 
Fix CVE-2024-41062.

Edward Adam Davis (1):
  bluetooth/l2cap: sync sock recv cb and release

Luiz Augusto von Dentz (2):
  Bluetooth: L2CAP: Fix deadlock
  Bluetooth: Fix usage of __hci_cmd_sync_status


-- 
2.34.1
 
https://gitee.com/src-openeuler/kernel/issues/IAGEK1 
 
Link:https://gitee.com/openeuler/kernel/pulls/10579

 

Reviewed-by: default avatarYue Haibing <yuehaibing@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 3cdb76a5 4d0bb954
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ int __hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
			     const void *param, u8 event, u32 timeout,
			     struct sock *sk);
int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
			const void *param, u32 timeout);

void hci_cmd_sync_init(struct hci_dev *hdev);
void hci_cmd_sync_clear(struct hci_dev *hdev);
+15 −54
Original line number Diff line number Diff line
@@ -63,50 +63,6 @@ DEFINE_MUTEX(hci_cb_list_lock);
/* HCI ID Numbering */
static DEFINE_IDA(hci_index_ida);

static int hci_scan_req(struct hci_request *req, unsigned long opt)
{
	__u8 scan = opt;

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

	/* Inquiry and Page scans */
	hci_req_add(req, HCI_OP_WRITE_SCAN_ENABLE, 1, &scan);
	return 0;
}

static int hci_auth_req(struct hci_request *req, unsigned long opt)
{
	__u8 auth = opt;

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

	/* Authentication */
	hci_req_add(req, HCI_OP_WRITE_AUTH_ENABLE, 1, &auth);
	return 0;
}

static int hci_encrypt_req(struct hci_request *req, unsigned long opt)
{
	__u8 encrypt = opt;

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

	/* Encryption */
	hci_req_add(req, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
	return 0;
}

static int hci_linkpol_req(struct hci_request *req, unsigned long opt)
{
	__le16 policy = cpu_to_le16(opt);

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

	/* Default link policy */
	hci_req_add(req, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
	return 0;
}

/* Get HCI device by index.
 * Device is held on return. */
struct hci_dev *hci_dev_get(int index)
@@ -728,6 +684,7 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
{
	struct hci_dev *hdev;
	struct hci_dev_req dr;
	__le16 policy;
	int err = 0;

	if (copy_from_user(&dr, arg, sizeof(dr)))
@@ -754,8 +711,8 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)

	switch (cmd) {
	case HCISETAUTH:
		err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
				   HCI_INIT_TIMEOUT, NULL);
		err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_AUTH_ENABLE,
					  1, &dr.dev_opt, HCI_CMD_TIMEOUT);
		break;

	case HCISETENCRYPT:
@@ -766,19 +723,21 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)

		if (!test_bit(HCI_AUTH, &hdev->flags)) {
			/* Auth must be enabled first */
			err = hci_req_sync(hdev, hci_auth_req, dr.dev_opt,
					   HCI_INIT_TIMEOUT, NULL);
			err = hci_cmd_sync_status(hdev,
						  HCI_OP_WRITE_AUTH_ENABLE,
						  1, &dr.dev_opt,
						  HCI_CMD_TIMEOUT);
			if (err)
				break;
		}

		err = hci_req_sync(hdev, hci_encrypt_req, dr.dev_opt,
				   HCI_INIT_TIMEOUT, NULL);
		err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_ENCRYPT_MODE,
					  1, &dr.dev_opt, HCI_CMD_TIMEOUT);
		break;

	case HCISETSCAN:
		err = hci_req_sync(hdev, hci_scan_req, dr.dev_opt,
				   HCI_INIT_TIMEOUT, NULL);
		err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_SCAN_ENABLE,
					  1, &dr.dev_opt, HCI_CMD_TIMEOUT);

		/* Ensure that the connectable and discoverable states
		 * get correctly modified as this was a non-mgmt change.
@@ -788,8 +747,10 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
		break;

	case HCISETLINKPOL:
		err = hci_req_sync(hdev, hci_linkpol_req, dr.dev_opt,
				   HCI_INIT_TIMEOUT, NULL);
		policy = cpu_to_le16(dr.dev_opt);

		err = hci_cmd_sync_status(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
					  2, &policy, HCI_CMD_TIMEOUT);
		break;

	case HCISETLINKMODE:
+13 −0
Original line number Diff line number Diff line
@@ -280,6 +280,19 @@ int __hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
}
EXPORT_SYMBOL(__hci_cmd_sync_status);

int hci_cmd_sync_status(struct hci_dev *hdev, u16 opcode, u32 plen,
			const void *param, u32 timeout)
{
	int err;

	hci_req_sync_lock(hdev);
	err = __hci_cmd_sync_status(hdev, opcode, plen, param, timeout);
	hci_req_sync_unlock(hdev);

	return err;
}
EXPORT_SYMBOL(hci_cmd_sync_status);

static void hci_cmd_sync_work(struct work_struct *work)
{
	struct hci_dev *hdev = container_of(work, struct hci_dev, cmd_sync_work);
+3 −0
Original line number Diff line number Diff line
@@ -6762,6 +6762,8 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,

	BT_DBG("chan %p, len %d", chan, skb->len);

	l2cap_chan_lock(chan);

	if (chan->state != BT_BOUND && chan->state != BT_CONNECTED)
		goto drop;

@@ -6778,6 +6780,7 @@ static void l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm,
	}

drop:
	l2cap_chan_unlock(chan);
	l2cap_chan_put(chan);
free_skb:
	kfree_skb(skb);
+11 −3
Original line number Diff line number Diff line
@@ -1238,6 +1238,10 @@ static void l2cap_sock_kill(struct sock *sk)

	BT_DBG("sk %p state %s", sk, state_to_string(sk->sk_state));

	/* Sock is dead, so set chan data to NULL, avoid other task use invalid
	 * sock pointer.
	 */
	l2cap_pi(sk)->chan->data = NULL;
	/* Kill poor orphan */

	l2cap_chan_put(l2cap_pi(sk)->chan);
@@ -1480,12 +1484,16 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)

static int l2cap_sock_recv_cb(struct l2cap_chan *chan, struct sk_buff *skb)
{
	struct sock *sk = chan->data;
	struct l2cap_pinfo *pi = l2cap_pi(sk);
	struct sock *sk;
	struct l2cap_pinfo *pi;
	int err;

	lock_sock(sk);
	sk = chan->data;
	if (!sk)
		return -ENXIO;

	pi = l2cap_pi(sk);
	lock_sock(sk);
	if (chan->mode == L2CAP_MODE_ERTM && !list_empty(&pi->rx_busy)) {
		err = -ENOMEM;
		goto done;