xfrm: Return error on unknown encap_type in init_state
authorHerbert Xu <herbert@gondor.apana.org.au>
Fri, 5 Jan 2018 11:12:32 +0000 (22:12 +1100)
committerSteffen Klassert <steffen.klassert@secunet.com>
Mon, 8 Jan 2018 06:17:52 +0000 (07:17 +0100)
Currently esp will happily create an xfrm state with an unknown
encap type for IPv4, without setting the necessary state parameters.
This patch fixes it by returning -EINVAL.

There is a similar problem in IPv6 where if the mode is unknown
we will skip initialisation while returning zero.  However, this
is harmless as the mode has already been checked further up the
stack.  This patch removes this anomaly by aligning the IPv6
behaviour with IPv4 and treating unknown modes (which cannot
actually happen) as transport mode.

Fixes: 38320c70d282 ("[IPSEC]: Use crypto_aead and authenc in ESP")
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
net/ipv4/esp4.c
net/ipv6/esp6.c

index d57aa64fa7c7d44307e6ecf9bf401c0a8ea21b87..61fe6e4d23fcb8d3cd2689566afa17c0952410b8 100644 (file)
@@ -981,6 +981,7 @@ static int esp_init_state(struct xfrm_state *x)
 
                switch (encap->encap_type) {
                default:
+                       err = -EINVAL;
                        goto error;
                case UDP_ENCAP_ESPINUDP:
                        x->props.header_len += sizeof(struct udphdr);
index a902ff8f59be3ed7e1f28afc234a0e56eca4e684..1a7f00cd4803b7d37160bfe8a161510b25d1ab89 100644 (file)
@@ -890,13 +890,12 @@ static int esp6_init_state(struct xfrm_state *x)
                        x->props.header_len += IPV4_BEET_PHMAXLEN +
                                               (sizeof(struct ipv6hdr) - sizeof(struct iphdr));
                break;
+       default:
        case XFRM_MODE_TRANSPORT:
                break;
        case XFRM_MODE_TUNNEL:
                x->props.header_len += sizeof(struct ipv6hdr);
                break;
-       default:
-               goto error;
        }
 
        align = ALIGN(crypto_aead_blocksize(aead), 4);