aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r--net/xfrm/xfrm_user.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 8bae6b22c846..d5e1e0b08890 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -26,6 +26,7 @@
26#include <net/sock.h> 26#include <net/sock.h>
27#include <net/xfrm.h> 27#include <net/xfrm.h>
28#include <net/netlink.h> 28#include <net/netlink.h>
29#include <net/ah.h>
29#include <asm/uaccess.h> 30#include <asm/uaccess.h>
30#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 31#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
31#include <linux/in6.h> 32#include <linux/in6.h>
@@ -148,7 +149,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
148 !attrs[XFRMA_ALG_AUTH_TRUNC]) || 149 !attrs[XFRMA_ALG_AUTH_TRUNC]) ||
149 attrs[XFRMA_ALG_AEAD] || 150 attrs[XFRMA_ALG_AEAD] ||
150 attrs[XFRMA_ALG_CRYPT] || 151 attrs[XFRMA_ALG_CRYPT] ||
151 attrs[XFRMA_ALG_COMP]) 152 attrs[XFRMA_ALG_COMP] ||
153 attrs[XFRMA_TFCPAD])
152 goto out; 154 goto out;
153 break; 155 break;
154 156
@@ -165,6 +167,9 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
165 attrs[XFRMA_ALG_CRYPT]) && 167 attrs[XFRMA_ALG_CRYPT]) &&
166 attrs[XFRMA_ALG_AEAD]) 168 attrs[XFRMA_ALG_AEAD])
167 goto out; 169 goto out;
170 if (attrs[XFRMA_TFCPAD] &&
171 p->mode != XFRM_MODE_TUNNEL)
172 goto out;
168 break; 173 break;
169 174
170 case IPPROTO_COMP: 175 case IPPROTO_COMP:
@@ -172,7 +177,8 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
172 attrs[XFRMA_ALG_AEAD] || 177 attrs[XFRMA_ALG_AEAD] ||
173 attrs[XFRMA_ALG_AUTH] || 178 attrs[XFRMA_ALG_AUTH] ||
174 attrs[XFRMA_ALG_AUTH_TRUNC] || 179 attrs[XFRMA_ALG_AUTH_TRUNC] ||
175 attrs[XFRMA_ALG_CRYPT]) 180 attrs[XFRMA_ALG_CRYPT] ||
181 attrs[XFRMA_TFCPAD])
176 goto out; 182 goto out;
177 break; 183 break;
178 184
@@ -186,6 +192,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
186 attrs[XFRMA_ALG_CRYPT] || 192 attrs[XFRMA_ALG_CRYPT] ||
187 attrs[XFRMA_ENCAP] || 193 attrs[XFRMA_ENCAP] ||
188 attrs[XFRMA_SEC_CTX] || 194 attrs[XFRMA_SEC_CTX] ||
195 attrs[XFRMA_TFCPAD] ||
189 !attrs[XFRMA_COADDR]) 196 !attrs[XFRMA_COADDR])
190 goto out; 197 goto out;
191 break; 198 break;
@@ -296,7 +303,8 @@ static int attach_auth_trunc(struct xfrm_algo_auth **algpp, u8 *props,
296 algo = xfrm_aalg_get_byname(ualg->alg_name, 1); 303 algo = xfrm_aalg_get_byname(ualg->alg_name, 1);
297 if (!algo) 304 if (!algo)
298 return -ENOSYS; 305 return -ENOSYS;
299 if (ualg->alg_trunc_len > algo->uinfo.auth.icv_fullbits) 306 if ((ualg->alg_trunc_len / 8) > MAX_AH_AUTH_LEN ||
307 ualg->alg_trunc_len > algo->uinfo.auth.icv_fullbits)
300 return -EINVAL; 308 return -EINVAL;
301 *props = algo->desc.sadb_alg_id; 309 *props = algo->desc.sadb_alg_id;
302 310
@@ -439,6 +447,9 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
439 goto error; 447 goto error;
440 } 448 }
441 449
450 if (attrs[XFRMA_TFCPAD])
451 x->tfcpad = nla_get_u32(attrs[XFRMA_TFCPAD]);
452
442 if (attrs[XFRMA_COADDR]) { 453 if (attrs[XFRMA_COADDR]) {
443 x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]), 454 x->coaddr = kmemdup(nla_data(attrs[XFRMA_COADDR]),
444 sizeof(*x->coaddr), GFP_KERNEL); 455 sizeof(*x->coaddr), GFP_KERNEL);
@@ -688,6 +699,9 @@ static int copy_to_user_state_extra(struct xfrm_state *x,
688 if (x->encap) 699 if (x->encap)
689 NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap); 700 NLA_PUT(skb, XFRMA_ENCAP, sizeof(*x->encap), x->encap);
690 701
702 if (x->tfcpad)
703 NLA_PUT_U32(skb, XFRMA_TFCPAD, x->tfcpad);
704
691 if (xfrm_mark_put(skb, &x->mark)) 705 if (xfrm_mark_put(skb, &x->mark))
692 goto nla_put_failure; 706 goto nla_put_failure;
693 707
@@ -2122,6 +2136,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
2122 [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) }, 2136 [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) },
2123 [XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) }, 2137 [XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) },
2124 [XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) }, 2138 [XFRMA_MARK] = { .len = sizeof(struct xfrm_mark) },
2139 [XFRMA_TFCPAD] = { .type = NLA_U32 },
2125}; 2140};
2126 2141
2127static struct xfrm_link { 2142static struct xfrm_link {
@@ -2174,7 +2189,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
2174 2189
2175 if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || 2190 if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
2176 type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && 2191 type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) &&
2177 (nlh->nlmsg_flags & NLM_F_DUMP)) { 2192 (nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) {
2178 if (link->dump == NULL) 2193 if (link->dump == NULL)
2179 return -EINVAL; 2194 return -EINVAL;
2180 2195
@@ -2301,6 +2316,8 @@ static inline size_t xfrm_sa_len(struct xfrm_state *x)
2301 l += nla_total_size(sizeof(*x->calg)); 2316 l += nla_total_size(sizeof(*x->calg));
2302 if (x->encap) 2317 if (x->encap)
2303 l += nla_total_size(sizeof(*x->encap)); 2318 l += nla_total_size(sizeof(*x->encap));
2319 if (x->tfcpad)
2320 l += nla_total_size(sizeof(x->tfcpad));
2304 if (x->security) 2321 if (x->security)
2305 l += nla_total_size(sizeof(struct xfrm_user_sec_ctx) + 2322 l += nla_total_size(sizeof(struct xfrm_user_sec_ctx) +
2306 x->security->ctx_len); 2323 x->security->ctx_len);