Commit 3ded0baf authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[IPSEC]: Move encap check back down to esp4.c

In a previous, I moved the encap_type checks in esp4.c from the packet
processing path to xfrm_user/af_key.  This isn't ideal since those encap
types only make sense for esp4.

The following patch moves it back into esp4.c.  The difference is
that it's now done in init_state so that it's only done once rather
than per-packet.

I've also added encap_type checks for every transform.  This means
that people attaching encap objects to AH/IPCOMP/IPIP will now get
errors.  That should be fine as no major KM does this.

Please note that the error returned is now EINVAL instead of
ENOPROTOOPT.  This shouldn't break anything since KMs only test
the errno from setsockopt() for NAT-T support rather than add_sa
where it would be too late anyway.
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@redhat.com>
parent 6567299a
...@@ -214,6 +214,9 @@ static int ah_init_state(struct xfrm_state *x, void *args) ...@@ -214,6 +214,9 @@ static int ah_init_state(struct xfrm_state *x, void *args)
if (x->aalg->alg_key_len > 512) if (x->aalg->alg_key_len > 512)
goto error; goto error;
if (x->encap)
goto error;
ahp = kmalloc(sizeof(*ahp), GFP_KERNEL); ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);
if (ahp == NULL) if (ahp == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -436,6 +436,7 @@ int esp_init_state(struct xfrm_state *x, void *args) ...@@ -436,6 +436,7 @@ int esp_init_state(struct xfrm_state *x, void *args)
switch (encap->encap_type) { switch (encap->encap_type) {
default: default:
goto error;
case UDP_ENCAP_ESPINUDP: case UDP_ENCAP_ESPINUDP:
x->props.header_len += sizeof(struct udphdr); x->props.header_len += sizeof(struct udphdr);
break; break;
...@@ -449,15 +450,9 @@ int esp_init_state(struct xfrm_state *x, void *args) ...@@ -449,15 +450,9 @@ int esp_init_state(struct xfrm_state *x, void *args)
return 0; return 0;
error: error:
if (esp) { x->data = esp;
if (esp->auth.tfm) esp_destroy(x);
crypto_free_tfm(esp->auth.tfm); x->data = NULL;
if (esp->auth.work_icv)
kfree(esp->auth.work_icv);
if (esp->conf.tfm)
crypto_free_tfm(esp->conf.tfm);
kfree(esp);
}
return -EINVAL; return -EINVAL;
} }
......
...@@ -288,6 +288,9 @@ static int ipcomp_init_state(struct xfrm_state *x, void *args) ...@@ -288,6 +288,9 @@ static int ipcomp_init_state(struct xfrm_state *x, void *args)
if (!x->calg) if (!x->calg)
goto out; goto out;
if (x->encap)
goto out;
err = -ENOMEM; err = -ENOMEM;
ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL); ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
if (!ipcd) if (!ipcd)
......
...@@ -84,6 +84,10 @@ static int ipip_init_state(struct xfrm_state *x, void *args) ...@@ -84,6 +84,10 @@ static int ipip_init_state(struct xfrm_state *x, void *args)
{ {
if (!x->props.mode) if (!x->props.mode)
return -EINVAL; return -EINVAL;
if (x->encap)
return -EINVAL;
x->props.header_len = sizeof(struct iphdr); x->props.header_len = sizeof(struct iphdr);
return 0; return 0;
......
...@@ -353,6 +353,9 @@ static int ah6_init_state(struct xfrm_state *x, void *args) ...@@ -353,6 +353,9 @@ static int ah6_init_state(struct xfrm_state *x, void *args)
if (x->aalg->alg_key_len > 512) if (x->aalg->alg_key_len > 512)
goto error; goto error;
if (x->encap)
goto error;
ahp = kmalloc(sizeof(*ahp), GFP_KERNEL); ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);
if (ahp == NULL) if (ahp == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -310,6 +310,9 @@ int esp6_init_state(struct xfrm_state *x, void *args) ...@@ -310,6 +310,9 @@ int esp6_init_state(struct xfrm_state *x, void *args)
if (x->ealg == NULL) if (x->ealg == NULL)
goto error; goto error;
if (x->encap)
goto error;
esp = kmalloc(sizeof(*esp), GFP_KERNEL); esp = kmalloc(sizeof(*esp), GFP_KERNEL);
if (esp == NULL) if (esp == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -284,6 +284,9 @@ static int ipcomp6_init_state(struct xfrm_state *x, void *args) ...@@ -284,6 +284,9 @@ static int ipcomp6_init_state(struct xfrm_state *x, void *args)
if (!x->calg) if (!x->calg)
goto out; goto out;
if (x->encap)
goto out;
err = -ENOMEM; err = -ENOMEM;
ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL); ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
if (!ipcd) if (!ipcd)
......
...@@ -517,6 +517,9 @@ static int xfrm6_tunnel_init_state(struct xfrm_state *x, void *args) ...@@ -517,6 +517,9 @@ static int xfrm6_tunnel_init_state(struct xfrm_state *x, void *args)
if (!x->props.mode) if (!x->props.mode)
return -EINVAL; return -EINVAL;
if (x->encap)
return -EINVAL;
x->props.header_len = sizeof(struct ipv6hdr); x->props.header_len = sizeof(struct ipv6hdr);
return 0; return 0;
......
...@@ -1075,15 +1075,6 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr, ...@@ -1075,15 +1075,6 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]; n_type = ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1];
natt->encap_type = n_type->sadb_x_nat_t_type_type; natt->encap_type = n_type->sadb_x_nat_t_type_type;
switch (natt->encap_type) {
case UDP_ENCAP_ESPINUDP:
case UDP_ENCAP_ESPINUDP_NON_IKE:
break;
default:
err = -ENOPROTOOPT;
goto out;
}
if (ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1]) { if (ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1]) {
struct sadb_x_nat_t_port* n_port = struct sadb_x_nat_t_port* n_port =
ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1]; ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1];
......
...@@ -78,15 +78,6 @@ static int verify_encap_tmpl(struct rtattr **xfrma) ...@@ -78,15 +78,6 @@ static int verify_encap_tmpl(struct rtattr **xfrma)
if ((rt->rta_len - sizeof(*rt)) < sizeof(*encap)) if ((rt->rta_len - sizeof(*rt)) < sizeof(*encap))
return -EINVAL; return -EINVAL;
encap = RTA_DATA(rt);
switch (encap->encap_type) {
case UDP_ENCAP_ESPINUDP:
case UDP_ENCAP_ESPINUDP_NON_IKE:
break;
default:
return -ENOPROTOOPT;
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment