diff options
| -rw-r--r-- | include/net/xfrm.h | 1 | ||||
| -rw-r--r-- | net/ipv6/ip6_vti.c | 4 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_tunnel.c | 3 | ||||
| -rw-r--r-- | net/key/af_key.c | 45 | ||||
| -rw-r--r-- | net/xfrm/xfrm_state.c | 6 |
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 { | |||
| 375 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo); | 375 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo); |
| 376 | int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo); | 376 | int xfrm_input_unregister_afinfo(const struct xfrm_input_afinfo *afinfo); |
| 377 | 377 | ||
| 378 | void xfrm_flush_gc(void); | ||
| 378 | void xfrm_state_delete_tunnel(struct xfrm_state *x); | 379 | void xfrm_state_delete_tunnel(struct xfrm_state *x); |
| 379 | 380 | ||
| 380 | struct xfrm_type { | 381 | struct 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 | ||
| 440 | static 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 | |||
| 448 | static 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 | |||
| 440 | static inline int pfkey_sec_ctx_len(const struct sadb_x_sec_ctx *sec_ctx) | 458 | static 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 | ||
| 2178 | void xfrm_flush_gc(void) | ||
| 2179 | { | ||
| 2180 | flush_work(&xfrm_state_gc_work); | ||
| 2181 | } | ||
| 2182 | EXPORT_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 */ |
| 2179 | void xfrm_state_delete_tunnel(struct xfrm_state *x) | 2185 | void xfrm_state_delete_tunnel(struct xfrm_state *x) |
| 2180 | { | 2186 | { |
