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

Revert "netfilter: x_tables: ensure last rule in base chain matches underflow/policy"

This reverts commit 0d7df906.

Valdis Kletnieks reported that xtables is broken in linux-next since
0d7df906  ("netfilter: x_tables: ensure last rule in base chain
matches underflow/policy"), as kernel rejects the (well-formed) ruleset:

[   64.402790] ip6_tables: last base chain position 1136 doesn't match underflow 1344 (hook 1)

mark_source_chains is not the correct place for such a check, as it
terminates evaluation of a chain once it sees an unconditional verdict
(following rules are known to be unreachable). It seems preferrable to
fix libiptc instead, so remove this check again.

Fixes: 0d7df906 ("netfilter: x_tables: ensure last rule in base chain matches underflow/policy")
Reported-by: default avatarValdis Kletnieks <valdis.kletnieks@vt.edu>
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 9ba5c404
...@@ -309,13 +309,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo, ...@@ -309,13 +309,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
for (hook = 0; hook < NF_ARP_NUMHOOKS; hook++) { for (hook = 0; hook < NF_ARP_NUMHOOKS; hook++) {
unsigned int pos = newinfo->hook_entry[hook]; unsigned int pos = newinfo->hook_entry[hook];
struct arpt_entry *e = entry0 + pos; struct arpt_entry *e = entry0 + pos;
unsigned int last_pos, depth;
if (!(valid_hooks & (1 << hook))) if (!(valid_hooks & (1 << hook)))
continue; continue;
depth = 0;
last_pos = pos;
/* Set initial back pointer. */ /* Set initial back pointer. */
e->counters.pcnt = pos; e->counters.pcnt = pos;
...@@ -346,8 +343,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo, ...@@ -346,8 +343,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
pos = e->counters.pcnt; pos = e->counters.pcnt;
e->counters.pcnt = 0; e->counters.pcnt = 0;
if (depth)
--depth;
/* We're at the start. */ /* We're at the start. */
if (pos == oldpos) if (pos == oldpos)
goto next; goto next;
...@@ -372,9 +367,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo, ...@@ -372,9 +367,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
if (!xt_find_jump_offset(offsets, newpos, if (!xt_find_jump_offset(offsets, newpos,
newinfo->number)) newinfo->number))
return 0; return 0;
if (entry0 + newpos != arpt_next_entry(e))
++depth;
} else { } else {
/* ... this is a fallthru */ /* ... this is a fallthru */
newpos = pos + e->next_offset; newpos = pos + e->next_offset;
...@@ -385,15 +377,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo, ...@@ -385,15 +377,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
e->counters.pcnt = pos; e->counters.pcnt = pos;
pos = newpos; pos = newpos;
} }
if (depth == 0)
last_pos = pos;
}
next:
if (last_pos != newinfo->underflow[hook]) {
pr_err_ratelimited("last base chain position %u doesn't match underflow %u (hook %u)\n",
last_pos, newinfo->underflow[hook], hook);
return 0;
} }
next: ;
} }
return 1; return 1;
} }
......
...@@ -378,13 +378,10 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -378,13 +378,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) { for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
unsigned int pos = newinfo->hook_entry[hook]; unsigned int pos = newinfo->hook_entry[hook];
struct ipt_entry *e = entry0 + pos; struct ipt_entry *e = entry0 + pos;
unsigned int last_pos, depth;
if (!(valid_hooks & (1 << hook))) if (!(valid_hooks & (1 << hook)))
continue; continue;
depth = 0;
last_pos = pos;
/* Set initial back pointer. */ /* Set initial back pointer. */
e->counters.pcnt = pos; e->counters.pcnt = pos;
...@@ -413,8 +410,6 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -413,8 +410,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
pos = e->counters.pcnt; pos = e->counters.pcnt;
e->counters.pcnt = 0; e->counters.pcnt = 0;
if (depth)
--depth;
/* We're at the start. */ /* We're at the start. */
if (pos == oldpos) if (pos == oldpos)
goto next; goto next;
...@@ -439,9 +434,6 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -439,9 +434,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
if (!xt_find_jump_offset(offsets, newpos, if (!xt_find_jump_offset(offsets, newpos,
newinfo->number)) newinfo->number))
return 0; return 0;
if (entry0 + newpos != ipt_next_entry(e))
++depth;
} else { } else {
/* ... this is a fallthru */ /* ... this is a fallthru */
newpos = pos + e->next_offset; newpos = pos + e->next_offset;
...@@ -452,15 +444,8 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -452,15 +444,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
e->counters.pcnt = pos; e->counters.pcnt = pos;
pos = newpos; pos = newpos;
} }
if (depth == 0)
last_pos = pos;
}
next:
if (last_pos != newinfo->underflow[hook]) {
pr_err_ratelimited("last base chain position %u doesn't match underflow %u (hook %u)\n",
last_pos, newinfo->underflow[hook], hook);
return 0;
} }
next: ;
} }
return 1; return 1;
} }
......
...@@ -396,13 +396,10 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -396,13 +396,10 @@ mark_source_chains(const struct xt_table_info *newinfo,
for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) { for (hook = 0; hook < NF_INET_NUMHOOKS; hook++) {
unsigned int pos = newinfo->hook_entry[hook]; unsigned int pos = newinfo->hook_entry[hook];
struct ip6t_entry *e = entry0 + pos; struct ip6t_entry *e = entry0 + pos;
unsigned int last_pos, depth;
if (!(valid_hooks & (1 << hook))) if (!(valid_hooks & (1 << hook)))
continue; continue;
depth = 0;
last_pos = pos;
/* Set initial back pointer. */ /* Set initial back pointer. */
e->counters.pcnt = pos; e->counters.pcnt = pos;
...@@ -431,8 +428,6 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -431,8 +428,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
pos = e->counters.pcnt; pos = e->counters.pcnt;
e->counters.pcnt = 0; e->counters.pcnt = 0;
if (depth)
--depth;
/* We're at the start. */ /* We're at the start. */
if (pos == oldpos) if (pos == oldpos)
goto next; goto next;
...@@ -457,9 +452,6 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -457,9 +452,6 @@ mark_source_chains(const struct xt_table_info *newinfo,
if (!xt_find_jump_offset(offsets, newpos, if (!xt_find_jump_offset(offsets, newpos,
newinfo->number)) newinfo->number))
return 0; return 0;
if (entry0 + newpos != ip6t_next_entry(e))
++depth;
} else { } else {
/* ... this is a fallthru */ /* ... this is a fallthru */
newpos = pos + e->next_offset; newpos = pos + e->next_offset;
...@@ -470,15 +462,8 @@ mark_source_chains(const struct xt_table_info *newinfo, ...@@ -470,15 +462,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
e->counters.pcnt = pos; e->counters.pcnt = pos;
pos = newpos; pos = newpos;
} }
if (depth == 0)
last_pos = pos;
}
next:
if (last_pos != newinfo->underflow[hook]) {
pr_err_ratelimited("last base chain position %u doesn't match underflow %u (hook %u)\n",
last_pos, newinfo->underflow[hook], hook);
return 0;
} }
next: ;
} }
return 1; return 1;
} }
......
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