diff options
Diffstat (limited to 'net/xfrm/xfrm_user.c')
-rw-r--r-- | net/xfrm/xfrm_user.c | 25 |
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 | ||
2127 | static struct xfrm_link { | 2142 | static 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); |