Bluetooth: Linearize skbs for use in BNEP, CMTP, HIDP, and RFCOMM
authorMat Martineau <mathewm@codeaurora.org>
Fri, 22 Jul 2011 21:53:58 +0000 (14:53 -0700)
committerGustavo F. Padovan <gustavo@padovan.org>
Tue, 27 Sep 2011 21:15:55 +0000 (18:15 -0300)
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>
net/bluetooth/bnep/core.c
net/bluetooth/cmtp/core.c
net/bluetooth/hidp/core.c
net/bluetooth/rfcomm/core.c

index d9edfe8bf9d677268cfc1f1e10b85f04d9f00f73..91bcd3a961ec22c501451ef588fe86b171c55ae3 100644 (file)
@@ -492,7 +492,10 @@ static int bnep_session(void *arg)
                /* RX */
                while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
                        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)
index 521baa4fe835eb775f24e59dda205ae76d1f87ce..7d00ddf9e9dcb55ab74cf768db31a3e15af647ac 100644 (file)
@@ -302,7 +302,10 @@ static int cmtp_session(void *arg)
 
                while ((skb = skb_dequeue(&sk->sk_receive_queue))) {
                        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);
index b83979c548b2ee706908a053430ad94a2df5a82c..075a3e920caffcbd44ff2f5a1e9e6ab4cc560e45 100644 (file)
@@ -716,12 +716,18 @@ static int hidp_session(void *arg)
 
                while ((skb = skb_dequeue(&ctrl_sk->sk_receive_queue))) {
                        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))) {
                        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);
index 5ba3f6df665cda5748044aaf21133f620979ca55..38b618c96de64a13a1d724a954352cec27264fae 100644 (file)
@@ -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);
-               rfcomm_recv_frame(s, skb);
+               if (!skb_linearize(skb))
+                       rfcomm_recv_frame(s, skb);
+               else
+                       kfree_skb(skb);
        }
 
        if (sk->sk_state == BT_CLOSED) {