diff options
author | Steffen Klassert <steffen.klassert@secunet.com> | 2017-05-03 02:44:27 -0400 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2017-05-04 01:27:26 -0400 |
commit | 0e78a87306a6f55b1c7bbafad1de62c3975953ca (patch) | |
tree | af330a0ac91610abacfa6bbb10eca116c34b55c5 | |
parent | f411af6822182f84834c4881b825dd40534e7fe8 (diff) |
esp4: Fix udpencap for local TCP packets.
Locally generated TCP packets are usually cloned, so we
do skb_cow_data() on this packets. After that we need to
reload the pointer to the esp header. On udpencap this
header has an offset to skb_transport_header, so take this
offset into account.
Fixes: 67d349ed603 ("net/esp4: Fix invalid esph pointer crash")
Fixes: fca11ebde3f0 ("esp4: Reorganize esp_output")
Reported-by: Don Bowman <db@donbowman.ca>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r-- | net/ipv4/esp4.c | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 65cc02bd82bc..93322f895eab 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -248,6 +248,7 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * | |||
248 | u8 *tail; | 248 | u8 *tail; |
249 | u8 *vaddr; | 249 | u8 *vaddr; |
250 | int nfrags; | 250 | int nfrags; |
251 | int esph_offset; | ||
251 | struct page *page; | 252 | struct page *page; |
252 | struct sk_buff *trailer; | 253 | struct sk_buff *trailer; |
253 | int tailen = esp->tailen; | 254 | int tailen = esp->tailen; |
@@ -313,11 +314,13 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * | |||
313 | } | 314 | } |
314 | 315 | ||
315 | cow: | 316 | cow: |
317 | esph_offset = (unsigned char *)esp->esph - skb_transport_header(skb); | ||
318 | |||
316 | nfrags = skb_cow_data(skb, tailen, &trailer); | 319 | nfrags = skb_cow_data(skb, tailen, &trailer); |
317 | if (nfrags < 0) | 320 | if (nfrags < 0) |
318 | goto out; | 321 | goto out; |
319 | tail = skb_tail_pointer(trailer); | 322 | tail = skb_tail_pointer(trailer); |
320 | esp->esph = ip_esp_hdr(skb); | 323 | esp->esph = (struct ip_esp_hdr *)(skb_transport_header(skb) + esph_offset); |
321 | 324 | ||
322 | skip_cow: | 325 | skip_cow: |
323 | esp_output_fill_trailer(tail, esp->tfclen, esp->plen, esp->proto); | 326 | esp_output_fill_trailer(tail, esp->tfclen, esp->plen, esp->proto); |