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 | |
| 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>
| -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); |
