* BUG: libiptc chain references bug
@ 2006-07-12 15:25 Jesper Dangaard Brouer
2006-07-13 11:17 ` Jesper Dangaard Brouer
0 siblings, 1 reply; 7+ messages in thread
From: Jesper Dangaard Brouer @ 2006-07-12 15:25 UTC (permalink / raw)
To: netfilter-devel
I have found a chain reference bug in libiptc or iptables.c.
When deleting a rule, with iptables do_command("-D xxx -j yyy") that
calls "iptc_delete_entry" the reference count of the rules jump
target chain is not decremented.
When deleting the rule with iptables do_command("-D xxx rule_num")
that calls "iptc_delete_num_entry" the reference count is correctly
decremeted.
Notice, that the chain gets the correct reference count after a
"commit" of the handle.
Here is the call sequence, of the bug:
+------
[Function] init() libiptc handle
[Function] create_chain(badehat)
[Function] iptables_do_command(-I FORWARD -j badehat)
[Function] get_references(badehat): refs=1
[Function] iptables_do_command(-D FORWARD -j badehat)
[Function] get_references(badehat): refs=1
[Function] commit()
System command: iptables -L badehat
Chain badehat (0 references)
target prot opt source destination
+------
Here is the call sequence, where the bug does not occur:
+------
[Function] init() libiptc handle
[Function] create_chain(badehat)
[Function] iptables_do_command(-I FORWARD -j badehat)
[Function] get_references(badehat): refs=1
[Function] iptables_do_command(-D FORWARD 1)
[Function] get_references(badehat): refs=0
[Function] commit()
System command: iptables -L badehat
Chain badehat (0 references)
target prot opt source destination
+------
Hilsen
Jesper Brouer
--
-------------------------------------------------------------------
MSc. Master of Computer Science
Dept. of Computer Science, University of Copenhagen
Author of http://www.adsl-optimizer.dk
-------------------------------------------------------------------
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: BUG: libiptc chain references bug
2006-07-12 15:25 BUG: libiptc chain references bug Jesper Dangaard Brouer
@ 2006-07-13 11:17 ` Jesper Dangaard Brouer
2006-07-14 12:29 ` [PATCH] " Jesper Dangaard Brouer
0 siblings, 1 reply; 7+ messages in thread
From: Jesper Dangaard Brouer @ 2006-07-13 11:17 UTC (permalink / raw)
To: netfilter-devel; +Cc: hawk
Hi
I have found the bug, and it's in libiptc.c.
More specifically in iptc_delete_entry() / TC_DELETE_ENTRY,
and is a result of constructing "r" the rule entry that is used for
comparison. The bug is that the function iptcc_map_target() increase the
target chains references count...
I'll cook up a patch, once I have tested it.
This call sequence reveals the bug. I'm trying to delete a rule that does
not exist, but during construction of "r" the match entry, the target
chain "badehat" gets its reference count incremented.
[Function] init() libiptc handle
[Function] create_chain(badehat)
[Function] get_references(badehat): refs=0
[Function] iptables_do_command(-D FORWARD -j badehat): No chain/target/match by that name
[Function] iptables_do_command(-D FORWARD -j badehat): No chain/target/match by that name
[Function] iptables_do_command(-D FORWARD -j badehat): No chain/target/match by that name
[Function] iptables_do_command(-D FORWARD -j badehat): No chain/target/match by that name
[Function] get_references(badehat): refs=4
[Function] commit()
--
Best regards
Jesper Brouer
ComX Networks A/S
Linux Network developer
Cand. Scient Datalog / MSc.
Author of http://adsl-optimizer.dk
On Wed, 12 Jul 2006, Jesper Dangaard Brouer wrote:
> I have found a chain reference bug in libiptc or iptables.c.
>
> When deleting a rule, with iptables do_command("-D xxx -j yyy") that
> calls "iptc_delete_entry" the reference count of the rules jump
> target chain is not decremented.
>
> When deleting the rule with iptables do_command("-D xxx rule_num")
> that calls "iptc_delete_num_entry" the reference count is correctly
> decremeted.
>
> Notice, that the chain gets the correct reference count after a
> "commit" of the handle.
>
>
> Here is the call sequence, of the bug:
>
> +------
> [Function] init() libiptc handle
> [Function] create_chain(badehat)
>
> [Function] iptables_do_command(-I FORWARD -j badehat)
> [Function] get_references(badehat): refs=1
>
> [Function] iptables_do_command(-D FORWARD -j badehat)
> [Function] get_references(badehat): refs=1
>
> [Function] commit()
>
> System command: iptables -L badehat
> Chain badehat (0 references)
> target prot opt source destination
> +------
>
> Here is the call sequence, where the bug does not occur:
>
> +------
> [Function] init() libiptc handle
> [Function] create_chain(badehat)
>
> [Function] iptables_do_command(-I FORWARD -j badehat)
> [Function] get_references(badehat): refs=1
>
> [Function] iptables_do_command(-D FORWARD 1)
> [Function] get_references(badehat): refs=0
>
> [Function] commit()
>
> System command: iptables -L badehat
> Chain badehat (0 references)
> target prot opt source destination
> +------
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH] BUG: libiptc chain references bug
2006-07-13 11:17 ` Jesper Dangaard Brouer
@ 2006-07-14 12:29 ` Jesper Dangaard Brouer
2006-07-16 15:01 ` Pablo Neira Ayuso
0 siblings, 1 reply; 7+ messages in thread
From: Jesper Dangaard Brouer @ 2006-07-14 12:29 UTC (permalink / raw)
To: Patrick McHardy, netfilter-devel; +Cc: hawk
[-- Attachment #1: Type: TEXT/PLAIN, Size: 695 bytes --]
Correcting a chain references increment bug in libiptc.
The bug lies in function iptc_delete_entry() / TC_DELETE_ENTRY. The
problem is the construction of "r" the rule entry, that is used for
comparison. The problem is that the function iptcc_map_target()
increase the target chains references count.
The fix is to use function iptcc_delete_rule() to delete the "r" rule
(as it decrement the counter again). To make it work a small NULL
pointer check is also added iptcc_delete_rule().
Signed-off-by: Jesper Dangaard Brouer <hawk@comx.dk>
--
Best regards
Jesper Brouer
ComX Networks A/S
Linux Network developer
Cand. Scient Datalog / MSc.
Author of http://adsl-optimizer.dk
[-- Attachment #2: Type: TEXT/PLAIN, Size: 1126 bytes --]
Index: iptables/libiptc/libiptc.c
===================================================================
--- iptables/libiptc/libiptc.c (revision 6644)
+++ iptables/libiptc/libiptc.c (working copy)
@@ -347,7 +347,8 @@ static void iptcc_delete_rule(struct rul
&& r->jump)
r->jump->references--;
- list_del(&r->list);
+ if (r->list.next && r->list.prev)
+ list_del(&r->list);
free(r);
}
@@ -1515,6 +1516,8 @@ TC_DELETE_ENTRY(const IPT_CHAINLABEL cha
memcpy(r->entry, origfw, origfw->next_offset);
r->counter_map.maptype = COUNTER_MAP_NOMAP;
+
+ /* Remember that iptcc_map_target increment target chain references */
if (!iptcc_map_target(*handle, r)) {
DEBUGP("unable to map target of rule for chain `%s'\n", chain);
free(r);
@@ -1542,13 +1545,13 @@ TC_DELETE_ENTRY(const IPT_CHAINLABEL cha
c->num_rules--;
iptcc_delete_rule(i);
+ iptcc_delete_rule(r); /* free and decrement references */
set_changed(*handle);
- free(r);
return 1;
}
- free(r);
+ iptcc_delete_rule(r); /* free and decrement references */
errno = ENOENT;
return 0;
}
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] BUG: libiptc chain references bug
2006-07-14 12:29 ` [PATCH] " Jesper Dangaard Brouer
@ 2006-07-16 15:01 ` Pablo Neira Ayuso
2006-07-16 20:19 ` Jesper Dangaard Brouer
0 siblings, 1 reply; 7+ messages in thread
From: Pablo Neira Ayuso @ 2006-07-16 15:01 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: hawk, netfilter-devel, Patrick McHardy
[-- Attachment #1: Type: text/plain, Size: 931 bytes --]
Hi Jesper,
Jesper Dangaard Brouer wrote:
>
> Correcting a chain references increment bug in libiptc.
>
> The bug lies in function iptc_delete_entry() / TC_DELETE_ENTRY. The
> problem is the construction of "r" the rule entry, that is used for
> comparison. The problem is that the function iptcc_map_target()
> increase the target chains references count.
>
> The fix is to use function iptcc_delete_rule() to delete the "r" rule
> (as it decrement the counter again). To make it work a small NULL
> pointer check is also added iptcc_delete_rule().
>
> Signed-off-by: Jesper Dangaard Brouer <hawk@comx.dk>
I don't like too much the is-the-rule-in-list checking in delete_entry,
please, could you tell me what you think about the patch attached? I
think it's cleaner. Thanks.
--
The dawn of the fourth age of Linux firewalling is coming; a time of
great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 637 bytes --]
Based on Jesper Dangaard Brouer's patch.
Index: libiptc/libiptc.c
===================================================================
--- libiptc/libiptc.c (revisión: 6644)
+++ libiptc/libiptc.c (copia de trabajo)
@@ -1543,6 +1543,14 @@
c->num_rules--;
iptcc_delete_rule(i);
+ /* Since iptcc_map_target increments refcounting of
+ * the target chain used by the fake rule, once we
+ * have matched it against the real rule, do not forget
+ * to drop the refcount that the fake rule holds */
+ if (r->type == IPTCC_R_JUMP
+ && r->jump)
+ r->jump->references--;
+
set_changed(*handle);
free(r);
return 1;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] BUG: libiptc chain references bug
2006-07-16 15:01 ` Pablo Neira Ayuso
@ 2006-07-16 20:19 ` Jesper Dangaard Brouer
2006-07-16 22:31 ` Pablo Neira Ayuso
2006-07-20 16:52 ` Patrick McHardy
0 siblings, 2 replies; 7+ messages in thread
From: Jesper Dangaard Brouer @ 2006-07-16 20:19 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: hawk, netfilter-devel, Patrick McHardy
[-- Attachment #1: Type: TEXT/PLAIN, Size: 2077 bytes --]
On Sun, 16 Jul 2006, Pablo Neira Ayuso wrote:
> Hi Jesper,
Hi Pablo, nice to hear from you!
> Jesper Dangaard Brouer wrote:
>>
>> Correcting a chain references increment bug in libiptc.
>>
>> The bug lies in function iptc_delete_entry() / TC_DELETE_ENTRY. The
>> problem is the construction of "r" the rule entry, that is used for
>> comparison. The problem is that the function iptcc_map_target()
>> increase the target chains references count.
>>
>> The fix is to use function iptcc_delete_rule() to delete the "r" rule
>> (as it decrement the counter again). To make it work a small NULL
>> pointer check is also added iptcc_delete_rule().
>>
>> Signed-off-by: Jesper Dangaard Brouer <hawk@comx.dk>
>
> I don't like too much the is-the-rule-in-list checking in delete_entry,
> please, could you tell me what you think about the patch attached? I think
> it's cleaner. Thanks.
First of all, (no offence) your patch will not work, as it does not catch
all control-flow cases. That is, if no match was found your patch does not
decrement the refcount. Hint, look at the places free(r) is called.
I have attached a patch, that does catch all cases. This is achived by
adding a else statement to the if statement where iptcc_map_target is
called.
I did consider, your strategy, but the reason I decided not to, was that I
though it was cleaner to always call "iptcc_delete_rule" when we want to
delete a rule, instead of free'ing it manually.
Well, I think Patrick should make the decision. As long as we fix the bug,
I don't care which patch goes in.
Cheers,
Jesper Brouer
p.s. Pablo, I was not going to piss in the bush... I was just discussing
with Gert Hansen about how dry the plant was... Perhaps the plant would
have preferred that I would have taken a leak... See you around ;-)
--
-------------------------------------------------------------------
MSc. Master of Computer Science
Dept. of Computer Science, University of Copenhagen
Author of http://www.adsl-optimizer.dk
-------------------------------------------------------------------
[-- Attachment #2: Type: TEXT/PLAIN, Size: 721 bytes --]
Index: libiptc/libiptc.c
===================================================================
--- libiptc/libiptc.c (revision 6644)
+++ libiptc/libiptc.c (working copy)
@@ -1518,8 +1518,16 @@ TC_DELETE_ENTRY(const IPT_CHAINLABEL cha
if (!iptcc_map_target(*handle, r)) {
DEBUGP("unable to map target of rule for chain `%s'\n", chain);
free(r);
return 0;
+ } else {
+ /* iptcc_map_target increment target chain references
+ * since this is a fake rule only used for matching
+ * the chain references count is decremented again.
+ */
+ if (r->type == IPTCC_R_JUMP
+ && r->jump)
+ r->jump->references--;
}
list_for_each_entry(i, &c->rules, list) {
unsigned char *mask;
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] BUG: libiptc chain references bug
2006-07-16 20:19 ` Jesper Dangaard Brouer
@ 2006-07-16 22:31 ` Pablo Neira Ayuso
2006-07-20 16:52 ` Patrick McHardy
1 sibling, 0 replies; 7+ messages in thread
From: Pablo Neira Ayuso @ 2006-07-16 22:31 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: hawk, netfilter-devel, Patrick McHardy
Jesper Dangaard Brouer wrote:
> On Sun, 16 Jul 2006, Pablo Neira Ayuso wrote:
>> Jesper Dangaard Brouer wrote:
>>>
>>> Correcting a chain references increment bug in libiptc.
>>>
>>> The bug lies in function iptc_delete_entry() / TC_DELETE_ENTRY. The
>>> problem is the construction of "r" the rule entry, that is used for
>>> comparison. The problem is that the function iptcc_map_target()
>>> increase the target chains references count.
>>>
>>> The fix is to use function iptcc_delete_rule() to delete the "r" rule
>>> (as it decrement the counter again). To make it work a small NULL
>>> pointer check is also added iptcc_delete_rule().
>>>
>>> Signed-off-by: Jesper Dangaard Brouer <hawk@comx.dk>
>>
>>
>> I don't like too much the is-the-rule-in-list checking in
>> delete_entry, please, could you tell me what you think about the patch
>> attached? I think it's cleaner. Thanks.
>
> First of all, (no offence) your patch will not work, as it does not
> catch all control-flow cases. That is, if no match was found your patch
> does not decrement the refcount. Hint, look at the places free(r) is
> called.
You are right, I missed that exit path.
> I have attached a patch, that does catch all cases. This is achived by
> adding a else statement to the if statement where iptcc_map_target is
> called.
I think I prefer this one, let see what Patrick thinks.
> I did consider, your strategy, but the reason I decided not to, was that
> I though it was cleaner to always call "iptcc_delete_rule" when we want
> to delete a rule, instead of free'ing it manually.
>
> Well, I think Patrick should make the decision. As long as we fix the
> bug, I don't care which patch goes in.
>
> Cheers,
> Jesper Brouer
>
> p.s. Pablo, I was not going to piss in the bush... I was just discussing
> with Gert Hansen about how dry the plant was... Perhaps the plant would
> have preferred that I would have taken a leak... See you around ;-)
That bush surely would prefer it these damned hot days of summer 8)
--
The dawn of the fourth age of Linux firewalling is coming; a time of
great struggle and heroic deeds -- J.Kadlecsik got inspired by J.Morris
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH] BUG: libiptc chain references bug
2006-07-16 20:19 ` Jesper Dangaard Brouer
2006-07-16 22:31 ` Pablo Neira Ayuso
@ 2006-07-20 16:52 ` Patrick McHardy
1 sibling, 0 replies; 7+ messages in thread
From: Patrick McHardy @ 2006-07-20 16:52 UTC (permalink / raw)
To: Jesper Dangaard Brouer; +Cc: hawk, netfilter-devel, Pablo Neira Ayuso
Jesper Dangaard Brouer wrote:
>
> On Sun, 16 Jul 2006, Pablo Neira Ayuso wrote:
>
>> I don't like too much the is-the-rule-in-list checking in
>> delete_entry, please, could you tell me what you think about the patch
>> attached? I think it's cleaner. Thanks.
>
>
> First of all, (no offence) your patch will not work, as it does not
> catch all control-flow cases. That is, if no match was found your patch
> does not decrement the refcount. Hint, look at the places free(r) is
> called.
>
> I have attached a patch, that does catch all cases. This is achived by
> adding a else statement to the if statement where iptcc_map_target is
> called.
>
> I did consider, your strategy, but the reason I decided not to, was that
> I though it was cleaner to always call "iptcc_delete_rule" when we want
> to delete a rule, instead of free'ing it manually.
>
> Well, I think Patrick should make the decision. As long as we fix the
> bug, I don't care which patch goes in.
I like the second patch better than the first one, so I've applied
this one. Thanks Jesper.
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2006-07-20 16:52 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-12 15:25 BUG: libiptc chain references bug Jesper Dangaard Brouer
2006-07-13 11:17 ` Jesper Dangaard Brouer
2006-07-14 12:29 ` [PATCH] " Jesper Dangaard Brouer
2006-07-16 15:01 ` Pablo Neira Ayuso
2006-07-16 20:19 ` Jesper Dangaard Brouer
2006-07-16 22:31 ` Pablo Neira Ayuso
2006-07-20 16:52 ` Patrick McHardy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.