diff options
author | Myungho Jung <mhjungk@gmail.com> | 2019-03-06 20:23:08 -0500 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2019-03-08 01:32:16 -0500 |
commit | 6ed69184ed9c43873b8a1ee721e3bf3c08c2c6be (patch) | |
tree | a98a3ee9e14b9896bef16ea1b842d4d6c3f7ce8d /net/ipv6 | |
parent | b805d78d300bcf2c83d6df7da0c818b0fee41427 (diff) |
xfrm: Reset secpath in xfrm failure
In esp4_gro_receive() and esp6_gro_receive(), secpath can be allocated
without adding xfrm state to xvec. Then, sp->xvec[sp->len - 1] would
fail and result in dereferencing invalid pointer in esp4_gso_segment()
and esp6_gso_segment(). Reset secpath if xfrm function returns error.
Fixes: 7785bba299a8 ("esp: Add a software GRO codepath")
Reported-by: syzbot+b69368fd933c6c592f4c@syzkaller.appspotmail.com
Signed-off-by: Myungho Jung <mhjungk@gmail.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/esp6_offload.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index d46b4eb645c2..cb99f6fb79b7 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c | |||
@@ -74,13 +74,13 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head, | |||
74 | goto out; | 74 | goto out; |
75 | 75 | ||
76 | if (sp->len == XFRM_MAX_DEPTH) | 76 | if (sp->len == XFRM_MAX_DEPTH) |
77 | goto out; | 77 | goto out_reset; |
78 | 78 | ||
79 | x = xfrm_state_lookup(dev_net(skb->dev), skb->mark, | 79 | x = xfrm_state_lookup(dev_net(skb->dev), skb->mark, |
80 | (xfrm_address_t *)&ipv6_hdr(skb)->daddr, | 80 | (xfrm_address_t *)&ipv6_hdr(skb)->daddr, |
81 | spi, IPPROTO_ESP, AF_INET6); | 81 | spi, IPPROTO_ESP, AF_INET6); |
82 | if (!x) | 82 | if (!x) |
83 | goto out; | 83 | goto out_reset; |
84 | 84 | ||
85 | sp->xvec[sp->len++] = x; | 85 | sp->xvec[sp->len++] = x; |
86 | sp->olen++; | 86 | sp->olen++; |
@@ -88,7 +88,7 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head, | |||
88 | xo = xfrm_offload(skb); | 88 | xo = xfrm_offload(skb); |
89 | if (!xo) { | 89 | if (!xo) { |
90 | xfrm_state_put(x); | 90 | xfrm_state_put(x); |
91 | goto out; | 91 | goto out_reset; |
92 | } | 92 | } |
93 | } | 93 | } |
94 | 94 | ||
@@ -109,6 +109,8 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head, | |||
109 | xfrm_input(skb, IPPROTO_ESP, spi, -2); | 109 | xfrm_input(skb, IPPROTO_ESP, spi, -2); |
110 | 110 | ||
111 | return ERR_PTR(-EINPROGRESS); | 111 | return ERR_PTR(-EINPROGRESS); |
112 | out_reset: | ||
113 | secpath_reset(skb); | ||
112 | out: | 114 | out: |
113 | skb_push(skb, offset); | 115 | skb_push(skb, offset); |
114 | NAPI_GRO_CB(skb)->same_flow = 0; | 116 | NAPI_GRO_CB(skb)->same_flow = 0; |