Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf

Pablo Neira Ayuso says:

====================
Netfilter fixes for net

1) Incorrect loop in error path of nft_set_elem_expr_clone(),
from Colin Ian King.

2) Missing xt_table_get_private_protected() to access table
private data in x_tables, from Subash Abhinov Kasiviswanathan.

3) Possible oops in ipset hash type resize, from Vasily Averin.

4) Fix shift-out-of-bounds in ipset hash type, also from Vasily.

* git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf:
netfilter: ipset: fix shift-out-of-bounds in htable_bits()
netfilter: ipset: fixes possible oops in mtype_resize
netfilter: x_tables: Update remaining dereference to RCU
netfilter: nftables: fix incorrect increment of loop counter
====================

Link: https://lore.kernel.org/r/20201218120409.3659-1-pablo@netfilter.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+23 -29
+1 -1
net/ipv4/netfilter/arp_tables.c
··· 1379 1379 xt_compat_lock(NFPROTO_ARP); 1380 1380 t = xt_find_table_lock(net, NFPROTO_ARP, get.name); 1381 1381 if (!IS_ERR(t)) { 1382 - const struct xt_table_info *private = t->private; 1382 + const struct xt_table_info *private = xt_table_get_private_protected(t); 1383 1383 struct xt_table_info info; 1384 1384 1385 1385 ret = compat_table_info(private, &info);
+1 -1
net/ipv4/netfilter/ip_tables.c
··· 1589 1589 xt_compat_lock(AF_INET); 1590 1590 t = xt_find_table_lock(net, AF_INET, get.name); 1591 1591 if (!IS_ERR(t)) { 1592 - const struct xt_table_info *private = t->private; 1592 + const struct xt_table_info *private = xt_table_get_private_protected(t); 1593 1593 struct xt_table_info info; 1594 1594 ret = compat_table_info(private, &info); 1595 1595 if (!ret && get.size == info.size)
+1 -1
net/ipv6/netfilter/ip6_tables.c
··· 1598 1598 xt_compat_lock(AF_INET6); 1599 1599 t = xt_find_table_lock(net, AF_INET6, get.name); 1600 1600 if (!IS_ERR(t)) { 1601 - const struct xt_table_info *private = t->private; 1601 + const struct xt_table_info *private = xt_table_get_private_protected(t); 1602 1602 struct xt_table_info info; 1603 1603 ret = compat_table_info(private, &info); 1604 1604 if (!ret && get.size == info.size)
+18 -24
net/netfilter/ipset/ip_set_hash_gen.h
··· 141 141 return hsize * sizeof(struct hbucket *) + sizeof(struct htable); 142 142 } 143 143 144 - /* Compute htable_bits from the user input parameter hashsize */ 145 - static u8 146 - htable_bits(u32 hashsize) 147 - { 148 - /* Assume that hashsize == 2^htable_bits */ 149 - u8 bits = fls(hashsize - 1); 150 - 151 - if (jhash_size(bits) != hashsize) 152 - /* Round up to the first 2^n value */ 153 - bits = fls(hashsize); 154 - 155 - return bits; 156 - } 157 - 158 144 #ifdef IP_SET_HASH_WITH_NETS 159 145 #if IPSET_NET_COUNT > 1 160 146 #define __CIDR(cidr, i) (cidr[i]) ··· 626 640 struct htype *h = set->data; 627 641 struct htable *t, *orig; 628 642 u8 htable_bits; 629 - size_t dsize = set->dsize; 643 + size_t hsize, dsize = set->dsize; 630 644 #ifdef IP_SET_HASH_WITH_NETS 631 645 u8 flags; 632 646 struct mtype_elem *tmp; ··· 650 664 retry: 651 665 ret = 0; 652 666 htable_bits++; 653 - if (!htable_bits) { 654 - /* In case we have plenty of memory :-) */ 655 - pr_warn("Cannot increase the hashsize of set %s further\n", 656 - set->name); 657 - ret = -IPSET_ERR_HASH_FULL; 658 - goto out; 659 - } 660 - t = ip_set_alloc(htable_size(htable_bits)); 667 + if (!htable_bits) 668 + goto hbwarn; 669 + hsize = htable_size(htable_bits); 670 + if (!hsize) 671 + goto hbwarn; 672 + t = ip_set_alloc(hsize); 661 673 if (!t) { 662 674 ret = -ENOMEM; 663 675 goto out; ··· 796 812 mtype_ahash_destroy(set, t, false); 797 813 if (ret == -EAGAIN) 798 814 goto retry; 815 + goto out; 816 + 817 + hbwarn: 818 + /* In case we have plenty of memory :-) */ 819 + pr_warn("Cannot increase the hashsize of set %s further\n", set->name); 820 + ret = -IPSET_ERR_HASH_FULL; 799 821 goto out; 800 822 } 801 823 ··· 1511 1521 if (!h) 1512 1522 return -ENOMEM; 1513 1523 1514 - hbits = htable_bits(hashsize); 1524 + /* Compute htable_bits from the user input parameter hashsize. 1525 + * Assume that hashsize == 2^htable_bits, 1526 + * otherwise round up to the first 2^n value. 1527 + */ 1528 + hbits = fls(hashsize - 1); 1515 1529 hsize = htable_size(hbits); 1516 1530 if (hsize == 0) { 1517 1531 kfree(h);
+2 -2
net/netfilter/nf_tables_api.c
··· 5254 5254 return 0; 5255 5255 5256 5256 err_expr: 5257 - for (k = i - 1; k >= 0; k++) 5258 - nft_expr_destroy(ctx, expr_array[i]); 5257 + for (k = i - 1; k >= 0; k--) 5258 + nft_expr_destroy(ctx, expr_array[k]); 5259 5259 5260 5260 return -ENOMEM; 5261 5261 }