Commit e816a2ce authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

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: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 1b293e30
...@@ -529,10 +529,15 @@ static int xt_check_entry_match(const char *match, const char *target, ...@@ -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) 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)); 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++) { for (i = 0; i < ARRAY_SIZE(info->hook_entry); i++) {
if (!(valid_hooks & (1 << i))) if (!(valid_hooks & (1 << i)))
continue; continue;
...@@ -541,9 +546,33 @@ int xt_check_table_hooks(const struct xt_table_info *info, unsigned int valid_ho ...@@ -541,9 +546,33 @@ int xt_check_table_hooks(const struct xt_table_info *info, unsigned int valid_ho
return -EINVAL; return -EINVAL;
if (info->underflow[i] == 0xFFFFFFFF) if (info->underflow[i] == 0xFFFFFFFF)
return -EINVAL; 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; return 0;
error:
pr_err_ratelimited("%s at hook %d\n", err, i);
return -EINVAL;
} }
EXPORT_SYMBOL(xt_check_table_hooks); EXPORT_SYMBOL(xt_check_table_hooks);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment