diff options
author | Gustavo F. Padovan <padovan@profusion.mobi> | 2010-05-01 15:15:45 -0400 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2010-05-10 03:28:53 -0400 |
commit | 4178ba462a3e8ab5094e69606f01d9e95f2d5ea6 (patch) | |
tree | 55370bd13670fc2166c88777ee2edec90005a8bc /net/bluetooth/l2cap.c | |
parent | dfc909befbfe967bd7f46ef33b6969c1b7f3cf42 (diff) |
Bluetooth: Prevents buffer overflow on l2cap_ertm_reassembly_sdu()
The checks should be done before the the memcpy to avoid buffer
overflow.
Reported-by: João Paulo Rechi Vita <jprvita@profusion.mobi>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/l2cap.c')
-rw-r--r-- | net/bluetooth/l2cap.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index fe663e9c6684..9ef01c32b3a2 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -3470,12 +3470,12 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c | |||
3470 | if (!pi->sdu) | 3470 | if (!pi->sdu) |
3471 | goto disconnect; | 3471 | goto disconnect; |
3472 | 3472 | ||
3473 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | ||
3474 | |||
3475 | pi->partial_sdu_len += skb->len; | 3473 | pi->partial_sdu_len += skb->len; |
3476 | if (pi->partial_sdu_len > pi->sdu_len) | 3474 | if (pi->partial_sdu_len > pi->sdu_len) |
3477 | goto drop; | 3475 | goto drop; |
3478 | 3476 | ||
3477 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | ||
3478 | |||
3479 | break; | 3479 | break; |
3480 | 3480 | ||
3481 | case L2CAP_SDU_END: | 3481 | case L2CAP_SDU_END: |
@@ -3486,8 +3486,6 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c | |||
3486 | goto disconnect; | 3486 | goto disconnect; |
3487 | 3487 | ||
3488 | if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) { | 3488 | if (!(pi->conn_state & L2CAP_CONN_SAR_RETRY)) { |
3489 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | ||
3490 | |||
3491 | pi->partial_sdu_len += skb->len; | 3489 | pi->partial_sdu_len += skb->len; |
3492 | 3490 | ||
3493 | if (pi->partial_sdu_len > pi->imtu) | 3491 | if (pi->partial_sdu_len > pi->imtu) |
@@ -3495,6 +3493,8 @@ static int l2cap_ertm_reassembly_sdu(struct sock *sk, struct sk_buff *skb, u16 c | |||
3495 | 3493 | ||
3496 | if (pi->partial_sdu_len != pi->sdu_len) | 3494 | if (pi->partial_sdu_len != pi->sdu_len) |
3497 | goto drop; | 3495 | goto drop; |
3496 | |||
3497 | memcpy(skb_put(pi->sdu, skb->len), skb->data, skb->len); | ||
3498 | } | 3498 | } |
3499 | 3499 | ||
3500 | _skb = skb_clone(pi->sdu, GFP_ATOMIC); | 3500 | _skb = skb_clone(pi->sdu, GFP_ATOMIC); |