diff options
author | João Paulo Rechi Vita <jprvita@profusion.mobi> | 2010-05-01 15:15:43 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-05-10 03:28:51 -0400 |
commit | 01760bdde9a92413b7fff928d08e19352bf09d82 (patch) | |
tree | 3bee629d9b15e71c92fbb799498f5cb0dd89ceb9 /net/bluetooth | |
parent | afefdbc4cf3b9d409d07e1e5264e7ff88bc48711 (diff) |
Bluetooth: Close L2CAP channel on invalid ReqSeq
Signed-off-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
Acked-by: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/l2cap.c | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 478def700c7c..31514d8faa66 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -3772,7 +3772,7 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3772 | struct sock *sk; | 3772 | struct sock *sk; |
3773 | struct l2cap_pinfo *pi; | 3773 | struct l2cap_pinfo *pi; |
3774 | u16 control, len; | 3774 | u16 control, len; |
3775 | u8 tx_seq; | 3775 | u8 tx_seq, req_seq, next_tx_seq_offset, req_seq_offset; |
3776 | 3776 | ||
3777 | sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); | 3777 | sk = l2cap_get_chan_by_scid(&conn->chan_list, cid); |
3778 | if (!sk) { | 3778 | if (!sk) { |
@@ -3823,6 +3823,22 @@ static inline int l2cap_data_channel(struct l2cap_conn *conn, u16 cid, struct sk | |||
3823 | if (l2cap_check_fcs(pi, skb)) | 3823 | if (l2cap_check_fcs(pi, skb)) |
3824 | goto drop; | 3824 | goto drop; |
3825 | 3825 | ||
3826 | req_seq = __get_reqseq(control); | ||
3827 | req_seq_offset = (req_seq - pi->expected_ack_seq) % 64; | ||
3828 | if (req_seq_offset < 0) | ||
3829 | req_seq_offset += 64; | ||
3830 | |||
3831 | next_tx_seq_offset = | ||
3832 | (pi->next_tx_seq - pi->expected_ack_seq) % 64; | ||
3833 | if (next_tx_seq_offset < 0) | ||
3834 | next_tx_seq_offset += 64; | ||
3835 | |||
3836 | /* check for invalid req-seq */ | ||
3837 | if (req_seq_offset > next_tx_seq_offset) { | ||
3838 | l2cap_send_disconn_req(pi->conn, sk); | ||
3839 | goto drop; | ||
3840 | } | ||
3841 | |||
3826 | if (__is_iframe(control)) { | 3842 | if (__is_iframe(control)) { |
3827 | if (len < 4) | 3843 | if (len < 4) |
3828 | goto drop; | 3844 | goto drop; |