Bluetooth: Check packet FCS earlier
authorGustavo F. Padovan <padovan@profusion.mobi>
Wed, 12 May 2010 01:02:00 +0000 (22:02 -0300)
committerMarcel Holtmann <marcel@holtmann.org>
Wed, 21 Jul 2010 17:39:07 +0000 (10:39 -0700)
This way, if FCS is enabled and the packet is corrupted, we just drop it
without read it len, which could be corrupted.

Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/l2cap.c

index 6094870d5d2a20df5e01f8ff36d153c36b80eb80..8c9f577dd46d1604e5c90acdcf024212d6312a55 100644 (file)
@@ -4166,25 +4166,25 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
                skb_pull(skb, 2);
                len = skb->len;
 
+               /*
+                * We can just drop the corrupted I-frame here.
+                * Receiver will miss it and start proper recovery
+                * procedures and ask retransmission.
+                */
+               if (l2cap_check_fcs(pi, skb))
+                       goto drop;
+
                if (__is_sar_start(control) && __is_iframe(control))
                        len -= 2;
 
                if (pi->fcs == L2CAP_FCS_CRC16)
                        len -= 2;
 
-               /*
-                * We can just drop the corrupted I-frame here.
-                * Receiver will miss it and start proper recovery
-                * procedures and ask retransmission.
-                */
                if (len > pi->mps) {
                        l2cap_send_disconn_req(pi->conn, sk);
                        goto drop;
                }
 
-               if (l2cap_check_fcs(pi, skb))
-                       goto drop;
-
                req_seq = __get_reqseq(control);
                req_seq_offset = (req_seq - pi->expected_ack_seq) % 64;
                if (req_seq_offset < 0)
@@ -4224,6 +4224,9 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
                skb_pull(skb, 2);
                len = skb->len;
 
+               if (l2cap_check_fcs(pi, skb))
+                       goto drop;
+
                if (__is_sar_start(control))
                        len -= 2;
 
@@ -4233,9 +4236,6 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk
                if (len > pi->mps || len < 0 || __is_sframe(control))
                        goto drop;
 
-               if (l2cap_check_fcs(pi, skb))
-                       goto drop;
-
                tx_seq = __get_txseq(control);
 
                if (pi->expected_tx_seq == tx_seq)