Skip to content

Commit

Permalink
Bluetooth: Fix SREJ_QUEUE corruption in L2CAP
Browse files Browse the repository at this point in the history
Since all TxSeq values are modulo, we shall not compare them directly. We
have to compare their offset inside the TxWindow instead.

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>
  • Loading branch information
João Paulo Rechi Vita authored and Marcel Holtmann committed Jul 21, 2010
1 parent 6e2b672 commit bfbacc1
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion net/bluetooth/l2cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -3394,6 +3394,8 @@ static inline void l2cap_send_i_or_rr_or_rnr(struct sock *sk)
static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_seq, u8 sar)
{
struct sk_buff *next_skb;
struct l2cap_pinfo *pi = l2cap_pi(sk);
int tx_seq_offset, next_tx_seq_offset;

bt_cb(skb)->tx_seq = tx_seq;
bt_cb(skb)->sar = sar;
Expand All @@ -3404,11 +3406,20 @@ static int l2cap_add_to_srej_queue(struct sock *sk, struct sk_buff *skb, u8 tx_s
return 0;
}

tx_seq_offset = (tx_seq - pi->buffer_seq) % 64;
if (tx_seq_offset < 0)
tx_seq_offset += 64;

do {
if (bt_cb(next_skb)->tx_seq == tx_seq)
return -EINVAL;

if (bt_cb(next_skb)->tx_seq > tx_seq) {
next_tx_seq_offset = (bt_cb(next_skb)->tx_seq -
pi->buffer_seq) % 64;
if (next_tx_seq_offset < 0)
next_tx_seq_offset += 64;

if (next_tx_seq_offset > tx_seq_offset) {
__skb_queue_before(SREJ_QUEUE(sk), next_skb, skb);
return 0;
}
Expand Down

0 comments on commit bfbacc1

Please sign in to comment.