Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44935720 authored by Mat Martineau's avatar Mat Martineau Committed by Gustavo F. Padovan
Browse files

Bluetooth: Linearize skbs for use in BNEP, CMTP, HIDP, and RFCOMM



Fragmented skbs are only encountered when receiving ERTM or streaming
mode L2CAP data.  BNEP, CMTP, HIDP, and RFCOMM generally use basic
mode, but they need to handle fragments without crashing.

Signed-off-by: default avatarMat Martineau <mathewm@codeaurora.org>
Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent 9fd481e0
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -492,7 +492,10 @@ static int bnep_session(void *arg)
		/* RX */
		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
			skb_orphan(skb);
			if (!skb_linearize(skb))
				bnep_rx_frame(s, skb);
			else
				kfree_skb(skb);
		}

		if (sk->sk_state != BT_CONNECTED)
+4 −1
Original line number Diff line number Diff line
@@ -302,7 +302,10 @@ static int cmtp_session(void *arg)

		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
			skb_orphan(skb);
			if (!skb_linearize(skb))
				cmtp_recv_frame(session, skb);
			else
				kfree_skb(skb);
		}

		cmtp_process_transmit(session);
+8 −2
Original line number Diff line number Diff line
@@ -716,12 +716,18 @@ static int hidp_session(void *arg)

		while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
			skb_orphan(skb);
			if (!skb_linearize(skb))
				hidp_recv_ctrl_frame(session, skb);
			else
				kfree_skb(skb);
		}

		while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
			skb_orphan(skb);
			if (!skb_linearize(skb))
				hidp_recv_intr_frame(session, skb);
			else
				kfree_skb(skb);
		}

		hidp_process_transmit(session);
+4 −1
Original line number Diff line number Diff line
@@ -1853,7 +1853,10 @@ static inline void rfcomm_process_rx(struct rfcomm_session *s)
	/* Get data directly from socket receive queue without copying it. */
	while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
		skb_orphan(skb);
		if (!skb_linearize(skb))
			rfcomm_recv_frame(s, skb);
		else
			kfree_skb(skb);
	}

	if (sk->sk_state == BT_CLOSED) {