esp: Fix memleaks on error paths.
We leak the temporary allocated resources in error paths, fix this by freeing them. Fixes:fca11ebde3
("esp4: Reorganize esp_output") Fixes:383d0350f2
("esp6: Reorganize esp_output") Fixes:3f29770723
("ipsec: check return value of skb_to_sgvec always") Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
This commit is contained in:
parent
edaf382518
commit
e619492323
@ -381,7 +381,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
|
|||||||
(unsigned char *)esph - skb->data,
|
(unsigned char *)esph - skb->data,
|
||||||
assoclen + ivlen + esp->clen + alen);
|
assoclen + ivlen + esp->clen + alen);
|
||||||
if (unlikely(err < 0))
|
if (unlikely(err < 0))
|
||||||
goto error;
|
goto error_free;
|
||||||
|
|
||||||
if (!esp->inplace) {
|
if (!esp->inplace) {
|
||||||
int allocsize;
|
int allocsize;
|
||||||
@ -392,7 +392,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
|
|||||||
spin_lock_bh(&x->lock);
|
spin_lock_bh(&x->lock);
|
||||||
if (unlikely(!skb_page_frag_refill(allocsize, pfrag, GFP_ATOMIC))) {
|
if (unlikely(!skb_page_frag_refill(allocsize, pfrag, GFP_ATOMIC))) {
|
||||||
spin_unlock_bh(&x->lock);
|
spin_unlock_bh(&x->lock);
|
||||||
goto error;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_shinfo(skb)->nr_frags = 1;
|
skb_shinfo(skb)->nr_frags = 1;
|
||||||
@ -409,7 +409,7 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
|
|||||||
(unsigned char *)esph - skb->data,
|
(unsigned char *)esph - skb->data,
|
||||||
assoclen + ivlen + esp->clen + alen);
|
assoclen + ivlen + esp->clen + alen);
|
||||||
if (unlikely(err < 0))
|
if (unlikely(err < 0))
|
||||||
goto error;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((x->props.flags & XFRM_STATE_ESN))
|
if ((x->props.flags & XFRM_STATE_ESN))
|
||||||
@ -442,8 +442,9 @@ int esp_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *
|
|||||||
|
|
||||||
if (sg != dsg)
|
if (sg != dsg)
|
||||||
esp_ssg_unref(x, tmp);
|
esp_ssg_unref(x, tmp);
|
||||||
kfree(tmp);
|
|
||||||
|
|
||||||
|
error_free:
|
||||||
|
kfree(tmp);
|
||||||
error:
|
error:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@ -695,8 +696,10 @@ skip_cow:
|
|||||||
|
|
||||||
sg_init_table(sg, nfrags);
|
sg_init_table(sg, nfrags);
|
||||||
err = skb_to_sgvec(skb, sg, 0, skb->len);
|
err = skb_to_sgvec(skb, sg, 0, skb->len);
|
||||||
if (unlikely(err < 0))
|
if (unlikely(err < 0)) {
|
||||||
|
kfree(tmp);
|
||||||
goto out;
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
skb->ip_summed = CHECKSUM_NONE;
|
skb->ip_summed = CHECKSUM_NONE;
|
||||||
|
|
||||||
|
@ -345,7 +345,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
|||||||
(unsigned char *)esph - skb->data,
|
(unsigned char *)esph - skb->data,
|
||||||
assoclen + ivlen + esp->clen + alen);
|
assoclen + ivlen + esp->clen + alen);
|
||||||
if (unlikely(err < 0))
|
if (unlikely(err < 0))
|
||||||
goto error;
|
goto error_free;
|
||||||
|
|
||||||
if (!esp->inplace) {
|
if (!esp->inplace) {
|
||||||
int allocsize;
|
int allocsize;
|
||||||
@ -356,7 +356,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
|||||||
spin_lock_bh(&x->lock);
|
spin_lock_bh(&x->lock);
|
||||||
if (unlikely(!skb_page_frag_refill(allocsize, pfrag, GFP_ATOMIC))) {
|
if (unlikely(!skb_page_frag_refill(allocsize, pfrag, GFP_ATOMIC))) {
|
||||||
spin_unlock_bh(&x->lock);
|
spin_unlock_bh(&x->lock);
|
||||||
goto error;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
skb_shinfo(skb)->nr_frags = 1;
|
skb_shinfo(skb)->nr_frags = 1;
|
||||||
@ -373,7 +373,7 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
|||||||
(unsigned char *)esph - skb->data,
|
(unsigned char *)esph - skb->data,
|
||||||
assoclen + ivlen + esp->clen + alen);
|
assoclen + ivlen + esp->clen + alen);
|
||||||
if (unlikely(err < 0))
|
if (unlikely(err < 0))
|
||||||
goto error;
|
goto error_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((x->props.flags & XFRM_STATE_ESN))
|
if ((x->props.flags & XFRM_STATE_ESN))
|
||||||
@ -406,8 +406,9 @@ int esp6_output_tail(struct xfrm_state *x, struct sk_buff *skb, struct esp_info
|
|||||||
|
|
||||||
if (sg != dsg)
|
if (sg != dsg)
|
||||||
esp_ssg_unref(x, tmp);
|
esp_ssg_unref(x, tmp);
|
||||||
kfree(tmp);
|
|
||||||
|
|
||||||
|
error_free:
|
||||||
|
kfree(tmp);
|
||||||
error:
|
error:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user