Merge branch 'master' of git://1984.lsi.us.es/nf

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.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+28 -31
+7 -26
net/ipv6/netfilter/ip6t_NPT.c
··· 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 ··· 66 85 return false; 67 86 } 68 87 69 - sum = csum16_add((__force __sum16)addr->s6_addr16[idx], 88 + sum = (__force __sum16) csum_add((__force __wsum)addr->s6_addr16[idx], 70 89 npt->adjustment); 71 90 if (sum == CSUM_MANGLED_0) 72 91 sum = 0;
+3
net/netfilter/Kconfig
··· 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
+18 -5
net/netfilter/xt_recent.c
··· 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 ··· 311 310 return ret; 312 311 } 313 312 313 + static void recent_table_free(void *addr) 314 + { 315 + if (is_vmalloc_addr(addr)) 316 + vfree(addr); 317 + else 318 + kfree(addr); 319 + } 320 + 314 321 static int recent_mt_check(const struct xt_mtchk_param *par, 315 322 const struct xt_recent_mtinfo_v1 *info) 316 323 { ··· 331 322 #endif 332 323 unsigned int i; 333 324 int ret = -EINVAL; 325 + size_t sz; 334 326 335 327 if (unlikely(!hash_rnd_inited)) { 336 328 get_random_bytes(&hash_rnd, sizeof(hash_rnd)); ··· 370 360 goto out; 371 361 } 372 362 373 - t = kzalloc(sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size, 374 - GFP_KERNEL); 363 + sz = sizeof(*t) + sizeof(t->iphash[0]) * ip_list_hash_size; 364 + if (sz <= PAGE_SIZE) 365 + t = kzalloc(sz, GFP_KERNEL); 366 + else 367 + t = vzalloc(sz); 375 368 if (t == NULL) { 376 369 ret = -ENOMEM; 377 370 goto out; ··· 390 377 uid = make_kuid(&init_user_ns, ip_list_uid); 391 378 gid = make_kgid(&init_user_ns, ip_list_gid); 392 379 if (!uid_valid(uid) || !gid_valid(gid)) { 393 - kfree(t); 380 + recent_table_free(t); 394 381 ret = -EINVAL; 395 382 goto out; 396 383 } 397 384 pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent, 398 385 &recent_mt_fops, t); 399 386 if (pde == NULL) { 400 - kfree(t); 387 + recent_table_free(t); 401 388 ret = -ENOMEM; 402 389 goto out; 403 390 } ··· 448 435 remove_proc_entry(t->name, recent_net->xt_recent); 449 436 #endif 450 437 recent_table_flush(t); 451 - kfree(t); 438 + recent_table_free(t); 452 439 } 453 440 mutex_unlock(&recent_mutex); 454 441 }