Просмотр исходного кода

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: Mat Martineau <mathewm@codeaurora.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Mat Martineau 14 лет назад
Родитель
Сommit
449357200c
4 измененных файлов с 20 добавлено и 5 удалено
  1. 4 1
      net/bluetooth/bnep/core.c
  2. 4 1
      net/bluetooth/cmtp/core.c
  3. 8 2
      net/bluetooth/hidp/core.c
  4. 4 1
      net/bluetooth/rfcomm/core.c

+ 4 - 1
net/bluetooth/bnep/core.c

@@ -492,7 +492,10 @@ static int bnep_session(void *arg)
 		/* RX */
 		/* RX */
 		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
 		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
 			skb_orphan(skb);
 			skb_orphan(skb);
-			bnep_rx_frame(s, skb);
+			if (!skb_linearize(skb))
+				bnep_rx_frame(s, skb);
+			else
+				kfree_skb(skb);
 		}
 		}
 
 
 		if (sk->sk_state != BT_CONNECTED)
 		if (sk->sk_state != BT_CONNECTED)

+ 4 - 1
net/bluetooth/cmtp/core.c

@@ -302,7 +302,10 @@ static int cmtp_session(void *arg)
 
 
 		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
 		while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
 			skb_orphan(skb);
 			skb_orphan(skb);
-			cmtp_recv_frame(session, skb);
+			if (!skb_linearize(skb))
+				cmtp_recv_frame(session, skb);
+			else
+				kfree_skb(skb);
 		}
 		}
 
 
 		cmtp_process_transmit(session);
 		cmtp_process_transmit(session);

+ 8 - 2
net/bluetooth/hidp/core.c

@@ -716,12 +716,18 @@ static int hidp_session(void *arg)
 
 
 		while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
 		while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
 			skb_orphan(skb);
 			skb_orphan(skb);
-			hidp_recv_ctrl_frame(session, skb);
+			if (!skb_linearize(skb))
+				hidp_recv_ctrl_frame(session, skb);
+			else
+				kfree_skb(skb);
 		}
 		}
 
 
 		while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
 		while ((skb = skb_dequeue(&intr_sk->sk_receive_queue))) {
 			skb_orphan(skb);
 			skb_orphan(skb);
-			hidp_recv_intr_frame(session, skb);
+			if (!skb_linearize(skb))
+				hidp_recv_intr_frame(session, skb);
+			else
+				kfree_skb(skb);
 		}
 		}
 
 
 		hidp_process_transmit(session);
 		hidp_process_transmit(session);

+ 4 - 1
net/bluetooth/rfcomm/core.c

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