Commit 1f9352ae authored by Patrick McHardy's avatar Patrick McHardy

netfilter: {ip,ip6,arp}_tables: fix incorrect loop detection

Commit e1b4b9f3 ([NETFILTER]: {ip,ip6,arp}_tables: fix exponential worst-case
search for loops) introduced a regression in the loop detection algorithm,
causing sporadic incorrectly detected loops.

When a chain has already been visited during the check, it is treated as
having a standard target containing a RETURN verdict directly at the
beginning in order to not check it again. The real target of the first
rule is then incorrectly treated as STANDARD target and checked not to
contain invalid verdicts.

Fix by making sure the rule does actually contain a standard target.

Based on patch by Francis Dupont <Francis_Dupont@isc.org>
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
parent af9d32ad
...@@ -388,7 +388,9 @@ static int mark_source_chains(struct xt_table_info *newinfo, ...@@ -388,7 +388,9 @@ static int mark_source_chains(struct xt_table_info *newinfo,
&& unconditional(&e->arp)) || visited) { && unconditional(&e->arp)) || visited) {
unsigned int oldpos, size; unsigned int oldpos, size;
if (t->verdict < -NF_MAX_VERDICT - 1) { if ((strcmp(t->target.u.user.name,
ARPT_STANDARD_TARGET) == 0) &&
t->verdict < -NF_MAX_VERDICT - 1) {
duprintf("mark_source_chains: bad " duprintf("mark_source_chains: bad "
"negative verdict (%i)\n", "negative verdict (%i)\n",
t->verdict); t->verdict);
......
...@@ -488,7 +488,9 @@ mark_source_chains(struct xt_table_info *newinfo, ...@@ -488,7 +488,9 @@ mark_source_chains(struct xt_table_info *newinfo,
&& unconditional(&e->ip)) || visited) { && unconditional(&e->ip)) || visited) {
unsigned int oldpos, size; unsigned int oldpos, size;
if (t->verdict < -NF_MAX_VERDICT - 1) { if ((strcmp(t->target.u.user.name,
IPT_STANDARD_TARGET) == 0) &&
t->verdict < -NF_MAX_VERDICT - 1) {
duprintf("mark_source_chains: bad " duprintf("mark_source_chains: bad "
"negative verdict (%i)\n", "negative verdict (%i)\n",
t->verdict); t->verdict);
......
...@@ -517,7 +517,9 @@ mark_source_chains(struct xt_table_info *newinfo, ...@@ -517,7 +517,9 @@ mark_source_chains(struct xt_table_info *newinfo,
&& unconditional(&e->ipv6)) || visited) { && unconditional(&e->ipv6)) || visited) {
unsigned int oldpos, size; unsigned int oldpos, size;
if (t->verdict < -NF_MAX_VERDICT - 1) { if ((strcmp(t->target.u.user.name,
IP6T_STANDARD_TARGET) == 0) &&
t->verdict < -NF_MAX_VERDICT - 1) {
duprintf("mark_source_chains: bad " duprintf("mark_source_chains: bad "
"negative verdict (%i)\n", "negative verdict (%i)\n",
t->verdict); t->verdict);
......
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