diff options
author | Herbert Xu <herbert@gondor.apana.org.au> | 2017-12-15 16:40:44 +1100 |
---|---|---|
committer | Ben Hutchings <ben@decadent.org.uk> | 2018-03-03 15:52:02 +0000 |
commit | 833760100588acfb267dac4d6a02ab9931237739 (patch) | |
tree | c0b0ba2f3865d97c94ca9613a28502bd983cfb50 /include/net | |
parent | 8bf6fe49ed4a05cab5420b04fd5c4ba84f7d34f6 (diff) |
xfrm: Reinject transport-mode packets through tasklet
commit acf568ee859f098279eadf551612f103afdacb4e upstream.
This is an old bugbear of mine:
https://www.mail-archive.com/netdev@vger.kernel.org/msg03894.html
By crafting special packets, it is possible to cause recursion
in our kernel when processing transport-mode packets at levels
that are only limited by packet size.
The easiest one is with DNAT, but an even worse one is where
UDP encapsulation is used in which case you just have to insert
an UDP encapsulation header in between each level of recursion.
This patch avoids this problem by reinjecting tranport-mode packets
through a tasklet.
Fixes: b05e106698d9 ("[IPV4/6]: Netfilter IPsec input hooks")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
[bwh: Backported to 3.16:
- netfilter finish callbacks only receive an sk_buff pointer
- Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/xfrm.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 4f2d16d375f3..0754305cd620 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1496,6 +1496,7 @@ int xfrm_init_state(struct xfrm_state *x); int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb); int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type); int xfrm_input_resume(struct sk_buff *skb, int nexthdr); +int xfrm_trans_queue(struct sk_buff *skb, int (*finish)(struct sk_buff *)); int xfrm_output_resume(struct sk_buff *skb, int err); int xfrm_output(struct sk_buff *skb); int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb); |