Pablo Neira Ayuso says: ==================== The following batch contains Netfilter fixes for 3.8-rc2, they are: * Fix IPv6 stateless network/port translation (NPT) checksum calculation, from Ulrich Weber. * Fix for xt_recent to avoid memory allocation failures if large hashtables are used, from Eric Dumazet. * Fix missing dependencies in Kconfig for the deprecated NOTRACK, from myself. ====================
Unified · Split
| @@ -14,42 +14,23 @@ · 13 unmodified lines | ||
| 14 | 14 | #include <linux/netfilter_ipv6/ip6t_NPT.h> |
| 15 | 15 | #include <linux/netfilter/x_tables.h> |
| 16 | 16 | |
| 17 | −static __sum16 csum16_complement(__sum16 a) | |
| 18 | −{ | |
| 19 | − return (__force __sum16)(0xffff - (__force u16)a); | |
| 20 | −} | |
| 21 | − | |
| 22 | −static __sum16 csum16_add(__sum16 a, __sum16 b) | |
| 23 | −{ | |
| 24 | − u16 sum; | |
| 25 | − | |
| 26 | − sum = (__force u16)a + (__force u16)b; | |
| 27 | − sum += (__force u16)a < (__force u16)b; | |
| 28 | − return (__force __sum16)sum; | |
| 29 | −} | |
| 30 | − | |
| 31 | −static __sum16 csum16_sub(__sum16 a, __sum16 b) | |
| 32 | −{ | |
| 33 | − return csum16_add(a, csum16_complement(b)); | |
| 34 | −} | |
| 35 | − | |
| 36 | 17 | static int ip6t_npt_checkentry(const struct xt_tgchk_param *par) |
| 37 | 18 | { |
| 38 | 19 | struct ip6t_npt_tginfo *npt = par->targinfo; |
| 39 | − __sum16 src_sum = 0, dst_sum = 0; | |
| 20 | + __wsum src_sum = 0, dst_sum = 0; | |
| 40 | 21 | unsigned int i; |
| 41 | 22 | |
| 42 | 23 | if (npt->src_pfx_len > 64 || npt->dst_pfx_len > 64) |
| 43 | 24 | return -EINVAL; |
| 44 | 25 | |
| 45 | 26 | for (i = 0; i < ARRAY_SIZE(npt->src_pfx.in6.s6_addr16); i++) { |
| 46 | − src_sum = csum16_add(src_sum, | |
| 47 | − (__force __sum16)npt->src_pfx.in6.s6_addr16[i]); | |
| 48 | − dst_sum = csum16_add(dst_sum, | |
| 49 | − (__force __sum16)npt->dst_pfx.in6.s6_addr16[i]); | |
| 27 | + src_sum = csum_add(src_sum, | |
| 28 | + (__force __wsum)npt->src_pfx.in6.s6_addr16[i]); | |
| 29 | + dst_sum = csum_add(dst_sum, | |
| 30 | + (__force __wsum)npt->dst_pfx.in6.s6_addr16[i]); | |
| 50 | 31 | } |
| 51 | 32 | |
| 52 | − npt->adjustment = csum16_sub(src_sum, dst_sum); | |
| 33 | + npt->adjustment = (__force __sum16) csum_sub(src_sum, dst_sum); | |
| 53 | 34 | return 0; |
| 54 | 35 | } |
| 55 | 36 | |
| @@ -85,7 +66,7 @@ static bool ip6t_npt_map_pfx(const struct ip6t_npt_tginfo *npt, · 29 unmodified lines | ||
| 85 | 66 | return false; |
| 86 | 67 | } |
| 87 | 68 | |
| 88 | − sum = csum16_add((__force __sum16)addr->s6_addr16[idx], | |
| 69 | + sum = (__force __sum16) csum_add((__force __wsum)addr->s6_addr16[idx], | |
| 89 | 70 | npt->adjustment); |
| 90 | 71 | if (sum == CSUM_MANGLED_0) |
| 91 | 72 | sum = 0; |
| @@ -682,6 +682,9 @@ config NETFILTER_XT_TARGET_NFQUEUE · 681 unmodified lines | ||
| 682 | 682 | |
| 683 | 683 | config NETFILTER_XT_TARGET_NOTRACK |
| 684 | 684 | tristate '"NOTRACK" target support (DEPRECATED)' |
| 685 | + depends on NF_CONNTRACK | |
| 686 | + depends on IP_NF_RAW || IP6_NF_RAW | |
| 687 | + depends on NETFILTER_ADVANCED | |
| 685 | 688 | select NETFILTER_XT_TARGET_CT |
| 686 | 689 | |
| 687 | 690 | config NETFILTER_XT_TARGET_RATEEST |
| @@ -29,6 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #include <linux/skbuff.h> |
| 30 | 30 | #include <linux/inet.h> |
| 31 | 31 | #include <linux/slab.h> |
| 32 | +#include <linux/vmalloc.h> | |
| 32 | 33 | #include <net/net_namespace.h> |
| 33 | 34 | #include <net/netns/generic.h> |
| 34 | 35 | |
| @@ -310,6 +311,14 @@ out: · 275 unmodified lines | ||
| 310 | 311 | return ret; |
| 311 | 312 | } |
| 312 | 313 | |
| 314 | +static void recent_table_free(void *addr) | |
| 315 | +{ | |
| 316 | + if (is_vmalloc_addr(addr)) | |
| 317 | + vfree(addr); | |
| 318 | + else | |
| 319 | + kfree(addr); | |
| 320 | +} | |
| 321 | + | |
| 313 | 322 | static int recent_mt_check(const struct xt_mtchk_param *par, |
| 314 | 323 | const struct xt_recent_mtinfo_v1 *info) |
| 315 | 324 | { |
| @@ -322,6 +331,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par, · 6 unmodified lines | ||
| 322 | 331 | #endif |
| 323 | 332 | unsigned int i; |
| 324 | 333 | int ret = -EINVAL; |
| 334 | + size_t sz; | |
| 325 | 335 | |
| 326 | 336 | if (unlikely(!hash_rnd_inited)) { |
| 327 | 337 | get_random_bytes(&hash_rnd, sizeof(hash_rnd)); |
| @@ -360,8 +370,11 @@ static int recent_mt_check(const struct xt_mtchk_param *par, · 32 unmodified lines | ||
| 360 | 370 | goto out; |
| 361 | 371 | } |
| 362 | 372 | |
| 363 | − t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size, | |
| 364 | − GFP_KERNEL); | |
| 373 | + sz = sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size; | |
| 374 | + if (sz <= PAGE_SIZE) | |
| 375 | + t = kzalloc(sz, GFP_KERNEL); | |
| 376 | + else | |
| 377 | + t = vzalloc(sz); | |
| 365 | 378 | if (t == NULL) { |
| 366 | 379 | ret = -ENOMEM; |
| 367 | 380 | goto out; |
| @@ -377,14 +390,14 @@ static int recent_mt_check(const struct xt_mtchk_param *par, · 9 unmodified lines | ||
| 377 | 390 | uid = make_kuid(&init_user_ns, ip_list_uid); |
| 378 | 391 | gid = make_kgid(&init_user_ns, ip_list_gid); |
| 379 | 392 | if (!uid_valid(uid) || !gid_valid(gid)) { |
| 380 | − kfree(t); | |
| 393 | + recent_table_free(t); | |
| 381 | 394 | ret = -EINVAL; |
| 382 | 395 | goto out; |
| 383 | 396 | } |
| 384 | 397 | pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent, |
| 385 | 398 | &recent_mt_fops, t); |
| 386 | 399 | if (pde == NULL) { |
| 387 | − kfree(t); | |
| 400 | + recent_table_free(t); | |
| 388 | 401 | ret = -ENOMEM; |
| 389 | 402 | goto out; |
| 390 | 403 | } |
| @@ -435,7 +448,7 @@ static void recent_mt_destroy(const struct xt_mtdtor_param *par) · 44 unmodified lines | ||
| 435 | 448 | remove_proc_entry(t->name, recent_net->xt_recent); |
| 436 | 449 | #endif |
| 437 | 450 | recent_table_flush(t); |
| 438 | − kfree(t); | |
| 451 | + recent_table_free(t); | |
| 439 | 452 | } |
| 440 | 453 | mutex_unlock(&recent_mutex); |
| 441 | 454 | } |