* 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.