My apologies if this has already been posted.
I've recently had a machine crash due to an appearant lack of memory. The
nature of this problem lead us to look for a memory leak in the kernel,
and we found a bug in the ipchains firewalling code. This doesn't affect
normal operation of most sites, but does cause the kernel to allocate one
100-byte buffer[1] (128-byte slab?) that is never freed again, every time
a rule is deleted using IP_FW_DELETE.
To reproduce, simply use the ipchains(8) utility to create a rule in any
firewall chain, then delete it again (by rule, not by number). Looking at
/proc/slabinfo before and after will show one additional size-128 block
being allocated every time. Repeat this 32 times, and the output of
free(1) or /proc/meminfo should also report 4k less memory free. Now
repeat at will, or until the box crashes. :)
The bug is caused by the code that handles IP_FW_DELETE requests. It
calls convert_ipfw(), which allocates and returns a new block of data,
that is used later in del_rule_from_chain() to compare and find the
matching rule. The rule itself is deleted from the chain and freed
properly, but the temporary ip_fwkern is not.
The patch is fairly simple:
--- linux-2.2.9/net/ipv4/ip_fw.c Tue May 25 18:41:16 1999
+++ linux/net/ipv4/ip_fw.c Tue May 25 19:07:05 1999
@@ -1408,8 +1408,10 @@
else if ((chain = find_label(new->fwc_label)) == NULL)
ret = ENOENT;
else if ((ip_fwkern = convert_ipfw(&new->fwc_rule, &ret))
- != NULL)
+ != NULL) {
ret = del_rule_from_chain(chain, ip_fwkern);
+ kfree(ip_fwkern);
+ }
}
break;
Please CC any replies to me directly, as I'm not subscribed to the list.
[1] This is likely to be different on an SMP machine.
-- Peter Tirsek, peter@tirsek.dk | "Linux is not user-friendly!" | "It _is_ user-friendly. It's just not In lack of a better .sig, | ignorant-friendly and idiot-friendly." this is all you get. :-) | -- Unknown
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/