netfilter: nf_tables: handle more than 8 * PAGE_SIZE set name allocations
We currently have a limit of 8 * PAGE_SIZE anonymous sets. Lift that limit by continuing the scan if the entire page is exhausted. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
d60ce62fb5
commit
60eb18943b
@ -2049,7 +2049,7 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
|
||||
const struct nft_set *i;
|
||||
const char *p;
|
||||
unsigned long *inuse;
|
||||
unsigned int n = 0;
|
||||
unsigned int n = 0, min = 0;
|
||||
|
||||
p = strnchr(name, IFNAMSIZ, '%');
|
||||
if (p != NULL) {
|
||||
@ -2059,23 +2059,28 @@ static int nf_tables_set_alloc_name(struct nft_ctx *ctx, struct nft_set *set,
|
||||
inuse = (unsigned long *)get_zeroed_page(GFP_KERNEL);
|
||||
if (inuse == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
cont:
|
||||
list_for_each_entry(i, &ctx->table->sets, list) {
|
||||
int tmp;
|
||||
|
||||
if (!sscanf(i->name, name, &tmp))
|
||||
continue;
|
||||
if (tmp < 0 || tmp >= BITS_PER_BYTE * PAGE_SIZE)
|
||||
if (tmp < min || tmp >= min + BITS_PER_BYTE * PAGE_SIZE)
|
||||
continue;
|
||||
|
||||
set_bit(tmp, inuse);
|
||||
set_bit(tmp - min, inuse);
|
||||
}
|
||||
|
||||
n = find_first_zero_bit(inuse, BITS_PER_BYTE * PAGE_SIZE);
|
||||
if (n >= BITS_PER_BYTE * PAGE_SIZE) {
|
||||
min += BITS_PER_BYTE * PAGE_SIZE;
|
||||
memset(inuse, 0, PAGE_SIZE);
|
||||
goto cont;
|
||||
}
|
||||
free_page((unsigned long)inuse);
|
||||
}
|
||||
|
||||
snprintf(set->name, sizeof(set->name), name, n);
|
||||
snprintf(set->name, sizeof(set->name), name, min + n);
|
||||
list_for_each_entry(i, &ctx->table->sets, list) {
|
||||
if (!strcmp(set->name, i->name))
|
||||
return -ENFILE;
|
||||
|
Loading…
Reference in New Issue
Block a user