Skip to content

Commit

Permalink
Bluetooth: Fix possible NULL pointer derefence in l2cap code
Browse files Browse the repository at this point in the history
Due to ERTM reliability L2CAP channel needs to be disconnected if
adding to srej list failed.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
  • Loading branch information
Szymon Janc authored and Gustavo F. Padovan committed Nov 16, 2011
1 parent 36acbb1 commit aef89f2
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions net/bluetooth/l2cap_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3788,7 +3788,7 @@ static void l2cap_resend_srejframe(struct l2cap_chan *chan, u16 tx_seq)
}
}

static void l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq)
static int l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq)
{
struct srej_list *new;
u32 control;
Expand All @@ -3799,6 +3799,9 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq)
l2cap_send_sframe(chan, control);

new = kzalloc(sizeof(struct srej_list), GFP_ATOMIC);
if (!new)
return -ENOMEM;

new->tx_seq = chan->expected_tx_seq;

chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq);
Expand All @@ -3807,6 +3810,8 @@ static void l2cap_send_srejframe(struct l2cap_chan *chan, u16 tx_seq)
}

chan->expected_tx_seq = __next_seq(chan, chan->expected_tx_seq);

return 0;
}

static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_control, struct sk_buff *skb)
Expand Down Expand Up @@ -3877,7 +3882,12 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_cont
return 0;
}
}
l2cap_send_srejframe(chan, tx_seq);

err = l2cap_send_srejframe(chan, tx_seq);
if (err < 0) {
l2cap_send_disconn_req(chan->conn, chan, -err);
return err;
}
}
} else {
expected_tx_seq_offset = __seq_offset(chan,
Expand All @@ -3899,7 +3909,11 @@ static inline int l2cap_data_channel_iframe(struct l2cap_chan *chan, u32 rx_cont

set_bit(CONN_SEND_PBIT, &chan->conn_state);

l2cap_send_srejframe(chan, tx_seq);
err = l2cap_send_srejframe(chan, tx_seq);
if (err < 0) {
l2cap_send_disconn_req(chan->conn, chan, -err);
return err;
}

__clear_ack_timer(chan);
}
Expand Down

0 comments on commit aef89f2

Please sign in to comment.