aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/xfrm.h1
-rw-r--r--net/ipv6/ip6_vti.c4
-rw-r--r--net/ipv6/xfrm6_tunnel.c3
-rw-r--r--net/key/af_key.c45
-rw-r--r--net/xfrm/xfrm_state.c6
5 files changed, 47 insertions, 12 deletions
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index a872379b69da..45e75c36b738 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -375,6 +375,7 @@ struct xfrm_input_afinfo {
375int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo); 375int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo);
376int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo); 376int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo);
377 377
378void xfrm_flush_gc(void);
378void xfrm_state_delete_tunnel(struct xfrm_state *x); 379void xfrm_state_delete_tunnel(struct xfrm_state *x);
379 380
380struct xfrm_type { 381struct xfrm_type {
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c
index c214ffec02f0..ca957dd93a29 100644
--- a/net/ipv6/ip6_vti.c
+++ b/net/ipv6/ip6_vti.c
@@ -669,7 +669,7 @@ static void vti6_link_config(struct ip6_tnl *t, bool keep_mtu)
669 else 669 else
670 mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr); 670 mtu = ETH_DATA_LEN - LL_MAX_HEADER - sizeof(struct ipv6hdr);
671 671
672 dev->mtu = max_t(int, mtu, IPV6_MIN_MTU); 672 dev->mtu = max_t(int, mtu, IPV4_MIN_MTU);
673} 673}
674 674
675/** 675/**
@@ -881,7 +881,7 @@ static void vti6_dev_setup(struct net_device *dev)
881 dev->priv_destructor = vti6_dev_free; 881 dev->priv_destructor = vti6_dev_free;
882 882
883 dev->type = ARPHRD_TUNNEL6; 883 dev->type = ARPHRD_TUNNEL6;
884 dev->min_mtu = IPV6_MIN_MTU; 884 dev->min_mtu = IPV4_MIN_MTU;
885 dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr); 885 dev->max_mtu = IP_MAX_MTU - sizeof(struct ipv6hdr);
886 dev->flags |= IFF_NOARP; 886 dev->flags |= IFF_NOARP;
887 dev->addr_len = sizeof(struct in6_addr); 887 dev->addr_len = sizeof(struct in6_addr);
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index f85f0d7480ac..4a46df8441c9 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -341,6 +341,9 @@ static void __net_exit xfrm6_tunnel_net_exit(struct net *net)
341 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net); 341 struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
342 unsigned int i; 342 unsigned int i;
343 343
344 xfrm_state_flush(net, IPSEC_PROTO_ANY, false);
345 xfrm_flush_gc();
346
344 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) 347 for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
345 WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i])); 348 WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i]));
346 349
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 7e2e7188e7f4..e62e52e8f141 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -437,6 +437,24 @@ static int verify_address_len(const void *p)
437 return 0; 437 return 0;
438} 438}
439 439
440static inline int sadb_key_len(const struct sadb_key *key)
441{
442 int key_bytes = DIV_ROUND_UP(key->sadb_key_bits, 8);
443
444 return DIV_ROUND_UP(sizeof(struct sadb_key) + key_bytes,
445 sizeof(uint64_t));
446}
447
448static int verify_key_len(const void *p)
449{
450 const struct sadb_key *key = p;
451
452 if (sadb_key_len(key) > key->sadb_key_len)
453 return -EINVAL;
454
455 return 0;
456}
457
440static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx) 458static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx)
441{ 459{
442 return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) + 460 return DIV_ROUND_UP(sizeof(struct sadb_x_sec_ctx) +
@@ -533,16 +551,25 @@ static int parse_exthdrs(struct sk_buff *skb, const struct sadb_msg *hdr, void *
533 return -EINVAL; 551 return -EINVAL;
534 if (ext_hdrs[ext_type-1] != NULL) 552 if (ext_hdrs[ext_type-1] != NULL)
535 return -EINVAL; 553 return -EINVAL;
536 if (ext_type == SADB_EXT_ADDRESS_SRC || 554 switch (ext_type) {
537 ext_type == SADB_EXT_ADDRESS_DST || 555 case SADB_EXT_ADDRESS_SRC:
538 ext_type == SADB_EXT_ADDRESS_PROXY || 556 case SADB_EXT_ADDRESS_DST:
539 ext_type == SADB_X_EXT_NAT_T_OA) { 557 case SADB_EXT_ADDRESS_PROXY:
558 case SADB_X_EXT_NAT_T_OA:
540 if (verify_address_len(p)) 559 if (verify_address_len(p))
541 return -EINVAL; 560 return -EINVAL;
542 } 561 break;
543 if (ext_type == SADB_X_EXT_SEC_CTX) { 562 case SADB_X_EXT_SEC_CTX:
544 if (verify_sec_ctx_len(p)) 563 if (verify_sec_ctx_len(p))
545 return -EINVAL; 564 return -EINVAL;
565 break;
566 case SADB_EXT_KEY_AUTH:
567 case SADB_EXT_KEY_ENCRYPT:
568 if (verify_key_len(p))
569 return -EINVAL;
570 break;
571 default:
572 break;
546 } 573 }
547 ext_hdrs[ext_type-1] = (void *) p; 574 ext_hdrs[ext_type-1] = (void *) p;
548 } 575 }
@@ -1104,14 +1131,12 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct net *net,
1104 key = ext_hdrs[SADB_EXT_KEY_AUTH - 1]; 1131 key = ext_hdrs[SADB_EXT_KEY_AUTH - 1];
1105 if (key != NULL && 1132 if (key != NULL &&
1106 sa->sadb_sa_auth != SADB_X_AALG_NULL && 1133 sa->sadb_sa_auth != SADB_X_AALG_NULL &&
1107 ((key->sadb_key_bits+7) / 8 == 0 || 1134 key->sadb_key_bits == 0)
1108 (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
1109 return ERR_PTR(-EINVAL); 1135 return ERR_PTR(-EINVAL);
1110 key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; 1136 key = ext_hdrs[SADB_EXT_KEY_ENCRYPT-1];
1111 if (key != NULL && 1137 if (key != NULL &&
1112 sa->sadb_sa_encrypt != SADB_EALG_NULL && 1138 sa->sadb_sa_encrypt != SADB_EALG_NULL &&
1113 ((key->sadb_key_bits+7) / 8 == 0 || 1139 key->sadb_key_bits == 0)
1114 (key->sadb_key_bits+7) / 8 > key->sadb_key_len * sizeof(uint64_t)))
1115 return ERR_PTR(-EINVAL); 1140 return ERR_PTR(-EINVAL);
1116 1141
1117 x = xfrm_state_alloc(net); 1142 x = xfrm_state_alloc(net);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f9d2f2233f09..6c177ae7a6d9 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2175,6 +2175,12 @@ struct xfrm_state_afinfo *xfrm_state_get_afinfo(unsigned int family)
2175 return afinfo; 2175 return afinfo;
2176} 2176}
2177 2177
2178void xfrm_flush_gc(void)
2179{
2180 flush_work(&xfrm_state_gc_work);
2181}
2182EXPORT_SYMBOL(xfrm_flush_gc);
2183
2178/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */ 2184/* Temporarily located here until net/xfrm/xfrm_tunnel.c is created */
2179void xfrm_state_delete_tunnel(struct xfrm_state *x) 2185void xfrm_state_delete_tunnel(struct xfrm_state *x)
2180{ 2186{