6.1-stable review patch. If anyone has any objections, please let me know.
------------------
From: Herbert Xu herbert@gondor.apana.org.au
commit 57010b8ece2821a1fdfdba2197d14a022f3769db upstream.
After the elimination of inner modes, a couple of warnings that were previously unreachable can now be triggered by malformed inbound packets.
Fix this by:
1. Moving the setting of skb->protocol into the decap functions. 2. Returning -EINVAL when unexpected protocol is seen.
Reported-by: Maciej Żenczykowskimaze@google.com Fixes: 5f24f41e8ea6 ("xfrm: Remove inner/outer modes from input path") Signed-off-by: Herbert Xu herbert@gondor.apana.org.au Reviewed-by: Maciej Żenczykowski maze@google.com Signed-off-by: Steffen Klassert steffen.klassert@secunet.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- net/xfrm/xfrm_input.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-)
--- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -180,6 +180,8 @@ static int xfrm4_remove_beet_encap(struc int optlen = 0; int err = -EINVAL;
+ skb->protocol = htons(ETH_P_IP); + if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) { struct ip_beet_phdr *ph; int phlen; @@ -232,6 +234,8 @@ static int xfrm4_remove_tunnel_encap(str { int err = -EINVAL;
+ skb->protocol = htons(ETH_P_IP); + if (!pskb_may_pull(skb, sizeof(struct iphdr))) goto out;
@@ -267,6 +271,8 @@ static int xfrm6_remove_tunnel_encap(str { int err = -EINVAL;
+ skb->protocol = htons(ETH_P_IPV6); + if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) goto out;
@@ -296,6 +302,8 @@ static int xfrm6_remove_beet_encap(struc int size = sizeof(struct ipv6hdr); int err;
+ skb->protocol = htons(ETH_P_IPV6); + err = skb_cow_head(skb, size + skb->mac_len); if (err) goto out; @@ -346,6 +354,7 @@ xfrm_inner_mode_encap_remove(struct xfrm return xfrm6_remove_tunnel_encap(x, skb); break; } + return -EINVAL; }
WARN_ON_ONCE(1); @@ -366,19 +375,6 @@ static int xfrm_prepare_input(struct xfr return -EAFNOSUPPORT; }
- switch (XFRM_MODE_SKB_CB(skb)->protocol) { - case IPPROTO_IPIP: - case IPPROTO_BEETPH: - skb->protocol = htons(ETH_P_IP); - break; - case IPPROTO_IPV6: - skb->protocol = htons(ETH_P_IPV6); - break; - default: - WARN_ON_ONCE(1); - break; - } - return xfrm_inner_mode_encap_remove(x, skb); }