mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-30 14:19:16 +00:00
netfilter: x_tables: enforce unique and ascending entry points
Harmless from kernel point of view, but iptables assumes that this is true when decoding a ruleset. iptables walks the dumped blob from kernel, and, for each entry that creates a new chain it prints out rule/chain information. Base chains (hook entry points) are thus only shown when they appear in the rule blob. One base chain that is referenced multiple times in hook blob is then only printed once. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
1b293e30f7
commit
e816a2ce49
1 changed files with 30 additions and 1 deletions
|
@ -529,10 +529,15 @@ static int xt_check_entry_match(const char *match, const char *target,
|
|||
*/
|
||||
int xt_check_table_hooks(const struct xt_table_info *info, unsigned int valid_hooks)
|
||||
{
|
||||
unsigned int i;
|
||||
const char *err = "unsorted underflow";
|
||||
unsigned int i, max_uflow, max_entry;
|
||||
bool check_hooks = false;
|
||||
|
||||
BUILD_BUG_ON(ARRAY_SIZE(info->hook_entry) != ARRAY_SIZE(info->underflow));
|
||||
|
||||
max_entry = 0;
|
||||
max_uflow = 0;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(info->hook_entry); i++) {
|
||||
if (!(valid_hooks & (1 << i)))
|
||||
continue;
|
||||
|
@ -541,9 +546,33 @@ int xt_check_table_hooks(const struct xt_table_info *info, unsigned int valid_ho
|
|||
return -EINVAL;
|
||||
if (info->underflow[i] == 0xFFFFFFFF)
|
||||
return -EINVAL;
|
||||
|
||||
if (check_hooks) {
|
||||
if (max_uflow > info->underflow[i])
|
||||
goto error;
|
||||
|
||||
if (max_uflow == info->underflow[i]) {
|
||||
err = "duplicate underflow";
|
||||
goto error;
|
||||
}
|
||||
if (max_entry > info->hook_entry[i]) {
|
||||
err = "unsorted entry";
|
||||
goto error;
|
||||
}
|
||||
if (max_entry == info->hook_entry[i]) {
|
||||
err = "duplicate entry";
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
max_entry = info->hook_entry[i];
|
||||
max_uflow = info->underflow[i];
|
||||
check_hooks = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
error:
|
||||
pr_err_ratelimited("%s at hook %d\n", err, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
EXPORT_SYMBOL(xt_check_table_hooks);
|
||||
|
||||
|
|
Loading…
Reference in a new issue