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

!9099 Bluetooth: L2CAP: Fix div-by-zero in l2cap_le_flowctl_init()

parents 2c312616 c0fd4f88
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1430,6 +1430,15 @@ struct hci_cp_le_set_event_mask {
	__u8     mask[8];
} __packed;

/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E
 * 7.8.2 LE Read Buffer Size command
 * MAX_LE_MTU is 0xffff.
 * 0 is also valid. It means that no dedicated LE Buffer exists.
 * It should use the HCI_Read_Buffer_Size command and mtu is shared
 * between BR/EDR and LE.
 */
#define HCI_MIN_LE_MTU 0x001b

#define HCI_OP_LE_READ_BUFFER_SIZE	0x2002
struct hci_rp_le_read_buffer_size {
	__u8     status;
+1 −0
Original line number Diff line number Diff line
@@ -607,6 +607,7 @@ struct hci_conn {
	__u8		resp_addr_type;
	__u16		handle;
	__u16		state;
	__u16		mtu;
	__u8		mode;
	__u8		type;
	__u8		role;
+26 −0
Original line number Diff line number Diff line
@@ -520,6 +520,27 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
{
	struct hci_conn *conn;

	switch (type) {
	case ACL_LINK:
		if (!hdev->acl_mtu)
			return NULL;
		break;
	case LE_LINK:
		if (hdev->le_mtu && hdev->le_mtu < HCI_MIN_LE_MTU)
			return NULL;
		if (!hdev->le_mtu && hdev->acl_mtu < HCI_MIN_LE_MTU)
			return NULL;
		break;
	case SCO_LINK:
	case ESCO_LINK:
		if (!hdev->sco_pkts)
			/* Controller does not support SCO or eSCO over HCI */
			return NULL;
		break;
	default:
		return NULL;
	}

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

	conn = kzalloc(sizeof(*conn), GFP_KERNEL);
@@ -553,10 +574,12 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
	switch (type) {
	case ACL_LINK:
		conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
		conn->mtu = hdev->acl_mtu;
		break;
	case LE_LINK:
		/* conn->src should reflect the local identity address */
		hci_copy_identity_address(hdev, &conn->src, &conn->src_type);
		conn->mtu = hdev->le_mtu ? hdev->le_mtu : hdev->acl_mtu;
		break;
	case SCO_LINK:
		if (lmp_esco_capable(hdev))
@@ -564,9 +587,12 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst,
					(hdev->esco_type & EDR_ESCO_MASK);
		else
			conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;

		conn->mtu = hdev->sco_mtu;
		break;
	case ESCO_LINK:
		conn->pkt_type = hdev->esco_type & ~EDR_ESCO_MASK;
		conn->mtu = hdev->sco_mtu;
		break;
	}

+8 −0
Original line number Diff line number Diff line
@@ -731,6 +731,10 @@ static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
	if (rp->status)
		return;

	if (!__le16_to_cpu(rp->acl_mtu) ||
	    !__le16_to_cpu(rp->acl_max_pkt))
		return;

	hdev->acl_mtu  = __le16_to_cpu(rp->acl_mtu);
	hdev->sco_mtu  = rp->sco_mtu;
	hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
@@ -1020,6 +1024,10 @@ static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
	if (rp->status)
		return;

	if (__le16_to_cpu(rp->le_mtu) &&
	    __le16_to_cpu(rp->le_mtu) < HCI_MIN_LE_MTU)
		return;

	hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
	hdev->le_pkts = rp->le_max_pkt;

+3 −14
Original line number Diff line number Diff line
@@ -7241,7 +7241,7 @@ static int l2cap_finish_move(struct l2cap_chan *chan)
	if (chan->hs_hcon)
		chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
	else
		chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
		chan->conn->mtu = chan->conn->hcon->mtu;

	return l2cap_resegment(chan);
}
@@ -7312,7 +7312,7 @@ static int l2cap_rx_state_wait_f(struct l2cap_chan *chan,
	if (chan->hs_hcon)
		chan->conn->mtu = chan->hs_hcon->hdev->block_mtu;
	else
		chan->conn->mtu = chan->conn->hcon->hdev->acl_mtu;
		chan->conn->mtu = chan->conn->hcon->mtu;

	err = l2cap_resegment(chan);

@@ -7863,18 +7863,7 @@ static struct l2cap_conn *l2cap_conn_add(struct hci_conn *hcon)

	BT_DBG("hcon %p conn %p hchan %p", hcon, conn, hchan);

	switch (hcon->type) {
	case LE_LINK:
		if (hcon->hdev->le_mtu) {
			conn->mtu = hcon->hdev->le_mtu;
			break;
		}
		fallthrough;
	default:
		conn->mtu = hcon->hdev->acl_mtu;
		break;
	}

	conn->mtu = hcon->mtu;
	conn->feat_mask = 0;

	conn->local_fixed_chan = L2CAP_FC_SIG_BREDR | L2CAP_FC_CONNLESS;
Loading