summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2004-08-15 05:43:06 -0700
committerDavid S. Miller <davem@kernel.bkbits.net>2004-08-15 05:43:06 -0700
commit3ded0baffb1ec366917d8d1434711897d5a41294 (patch)
treeffc2b4420018d022e7cc32bce5a3939c0c80361f
parent6567299ad27fb7c0b21d23ccd732b14304184578 (diff)
[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: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@redhat.com>
-rw-r--r--net/ipv4/ah4.c3
-rw-r--r--net/ipv4/esp4.c13
-rw-r--r--net/ipv4/ipcomp.c3
-rw-r--r--net/ipv4/xfrm4_tunnel.c4
-rw-r--r--net/ipv6/ah6.c3
-rw-r--r--net/ipv6/esp6.c3
-rw-r--r--net/ipv6/ipcomp6.c3
-rw-r--r--net/ipv6/xfrm6_tunnel.c3
-rw-r--r--net/key/af_key.c9
-rw-r--r--net/xfrm/xfrm_user.c9
10 files changed, 26 insertions, 27 deletions
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 9784f0376980..b345043f51dd 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -214,6 +214,9 @@ static int ah_init_state(struct xfrm_state *x, void *args)
if (x->aalg->alg_key_len > 512)
goto error;
+ if (x->encap)
+ goto error;
+
ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);
if (ahp == NULL)
return -ENOMEM;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 07a594b831d2..c8cd0c7de3ea 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -436,6 +436,7 @@ int esp_init_state(struct xfrm_state *x, void *args)
switch (encap->encap_type) {
default:
+ goto error;
case UDP_ENCAP_ESPINUDP:
x->props.header_len += sizeof(struct udphdr);
break;
@@ -449,15 +450,9 @@ int esp_init_state(struct xfrm_state *x, void *args)
return 0;
error:
- if (esp) {
- if (esp->auth.tfm)
- crypto_free_tfm(esp->auth.tfm);
- if (esp->auth.work_icv)
- kfree(esp->auth.work_icv);
- if (esp->conf.tfm)
- crypto_free_tfm(esp->conf.tfm);
- kfree(esp);
- }
+ x->data = esp;
+ esp_destroy(x);
+ x->data = NULL;
return -EINVAL;
}
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 7ce7469a3c04..b3885885abf0 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -288,6 +288,9 @@ static int ipcomp_init_state(struct xfrm_state *x, void *args)
if (!x->calg)
goto out;
+ if (x->encap)
+ goto out;
+
err = -ENOMEM;
ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
if (!ipcd)
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 0d1a0b0c7901..9f04c5706aac 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -84,6 +84,10 @@ static int ipip_init_state(struct xfrm_state *x, void *args)
{
if (!x->props.mode)
return -EINVAL;
+
+ if (x->encap)
+ return -EINVAL;
+
x->props.header_len = sizeof(struct iphdr);
return 0;
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index eda2737e572b..28bac499f839 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -353,6 +353,9 @@ static int ah6_init_state(struct xfrm_state *x, void *args)
if (x->aalg->alg_key_len > 512)
goto error;
+ if (x->encap)
+ goto error;
+
ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);
if (ahp == NULL)
return -ENOMEM;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index c80152a70efc..eb94426df27e 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -310,6 +310,9 @@ int esp6_init_state(struct xfrm_state *x, void *args)
if (x->ealg == NULL)
goto error;
+ if (x->encap)
+ goto error;
+
esp = kmalloc(sizeof(*esp), GFP_KERNEL);
if (esp == NULL)
return -ENOMEM;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 04303769d36b..ee62dba1b3ca 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -284,6 +284,9 @@ static int ipcomp6_init_state(struct xfrm_state *x, void *args)
if (!x->calg)
goto out;
+ if (x->encap)
+ goto out;
+
err = -ENOMEM;
ipcd = kmalloc(sizeof(*ipcd), GFP_KERNEL);
if (!ipcd)
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 5766a133411a..fb5b34a0d4c4 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -517,6 +517,9 @@ static int xfrm6_tunnel_init_state(struct xfrm_state *x, void *args)
if (!x->props.mode)
return -EINVAL;
+ if (x->encap)
+ return -EINVAL;
+
x->props.header_len = sizeof(struct ipv6hdr);
return 0;
diff --git a/net/key/af_key.c b/net/key/af_key.c
index fdf75a1ba801..8ca25fd7efe7 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -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];
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]) {
struct sadb_x_nat_t_port* n_port =
ext_hdrs[SADB_X_EXT_NAT_T_SPORT-1];
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2b42dc25571c..be298cde3022 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -78,15 +78,6 @@ static int verify_encap_tmpl(struct rtattr **xfrma)
if ((rt->rta_len - sizeof(*rt)) < sizeof(*encap))
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;
}