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>
This commit is contained in:
Коммит
1e72faedcd
|
@ -1379,7 +1379,7 @@ static int compat_get_entries(struct net *net,
|
|||
xt_compat_lock(NFPROTO_ARP);
|
||||
t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
|
||||
if (!IS_ERR(t)) {
|
||||
const struct xt_table_info *private = t->private;
|
||||
const struct xt_table_info *private = xt_table_get_private_protected(t);
|
||||
struct xt_table_info info;
|
||||
|
||||
ret = compat_table_info(private, &info);
|
||||
|
|
|
@ -1589,7 +1589,7 @@ compat_get_entries(struct net *net, struct compat_ipt_get_entries __user *uptr,
|
|||
xt_compat_lock(AF_INET);
|
||||
t = xt_find_table_lock(net, AF_INET, get.name);
|
||||
if (!IS_ERR(t)) {
|
||||
const struct xt_table_info *private = t->private;
|
||||
const struct xt_table_info *private = xt_table_get_private_protected(t);
|
||||
struct xt_table_info info;
|
||||
ret = compat_table_info(private, &info);
|
||||
if (!ret && get.size == info.size)
|
||||
|
|
|
@ -1598,7 +1598,7 @@ compat_get_entries(struct net *net, struct compat_ip6t_get_entries __user *uptr,
|
|||
xt_compat_lock(AF_INET6);
|
||||
t = xt_find_table_lock(net, AF_INET6, get.name);
|
||||
if (!IS_ERR(t)) {
|
||||
const struct xt_table_info *private = t->private;
|
||||
const struct xt_table_info *private = xt_table_get_private_protected(t);
|
||||
struct xt_table_info info;
|
||||
ret = compat_table_info(private, &info);
|
||||
if (!ret && get.size == info.size)
|
||||
|
|
|
@ -141,20 +141,6 @@ htable_size(u8 hbits)
|
|||
return hsize * sizeof(struct hbucket *) + sizeof(struct htable);
|
||||
}
|
||||
|
||||
/* Compute htable_bits from the user input parameter hashsize */
|
||||
static u8
|
||||
htable_bits(u32 hashsize)
|
||||
{
|
||||
/* Assume that hashsize == 2^htable_bits */
|
||||
u8 bits = fls(hashsize - 1);
|
||||
|
||||
if (jhash_size(bits) != hashsize)
|
||||
/* Round up to the first 2^n value */
|
||||
bits = fls(hashsize);
|
||||
|
||||
return bits;
|
||||
}
|
||||
|
||||
#ifdef IP_SET_HASH_WITH_NETS
|
||||
#if IPSET_NET_COUNT > 1
|
||||
#define __CIDR(cidr, i) (cidr[i])
|
||||
|
@ -640,7 +626,7 @@ mtype_resize(struct ip_set *set, bool retried)
|
|||
struct htype *h = set->data;
|
||||
struct htable *t, *orig;
|
||||
u8 htable_bits;
|
||||
size_t dsize = set->dsize;
|
||||
size_t hsize, dsize = set->dsize;
|
||||
#ifdef IP_SET_HASH_WITH_NETS
|
||||
u8 flags;
|
||||
struct mtype_elem *tmp;
|
||||
|
@ -664,14 +650,12 @@ mtype_resize(struct ip_set *set, bool retried)
|
|||
retry:
|
||||
ret = 0;
|
||||
htable_bits++;
|
||||
if (!htable_bits) {
|
||||
/* In case we have plenty of memory :-) */
|
||||
pr_warn("Cannot increase the hashsize of set %s further\n",
|
||||
set->name);
|
||||
ret = -IPSET_ERR_HASH_FULL;
|
||||
goto out;
|
||||
}
|
||||
t = ip_set_alloc(htable_size(htable_bits));
|
||||
if (!htable_bits)
|
||||
goto hbwarn;
|
||||
hsize = htable_size(htable_bits);
|
||||
if (!hsize)
|
||||
goto hbwarn;
|
||||
t = ip_set_alloc(hsize);
|
||||
if (!t) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
|
@ -813,6 +797,12 @@ cleanup:
|
|||
if (ret == -EAGAIN)
|
||||
goto retry;
|
||||
goto out;
|
||||
|
||||
hbwarn:
|
||||
/* In case we have plenty of memory :-) */
|
||||
pr_warn("Cannot increase the hashsize of set %s further\n", set->name);
|
||||
ret = -IPSET_ERR_HASH_FULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Get the current number of elements and ext_size in the set */
|
||||
|
@ -1521,7 +1511,11 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set,
|
|||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
hbits = htable_bits(hashsize);
|
||||
/* Compute htable_bits from the user input parameter hashsize.
|
||||
* Assume that hashsize == 2^htable_bits,
|
||||
* otherwise round up to the first 2^n value.
|
||||
*/
|
||||
hbits = fls(hashsize - 1);
|
||||
hsize = htable_size(hbits);
|
||||
if (hsize == 0) {
|
||||
kfree(h);
|
||||
|
|
|
@ -5254,8 +5254,8 @@ static int nft_set_elem_expr_clone(const struct nft_ctx *ctx,
|
|||
return 0;
|
||||
|
||||
err_expr:
|
||||
for (k = i - 1; k >= 0; k++)
|
||||
nft_expr_destroy(ctx, expr_array[i]);
|
||||
for (k = i - 1; k >= 0; k--)
|
||||
nft_expr_destroy(ctx, expr_array[k]);
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче