From: Pablo Neira <pablo@eurodev.net>
To: Netfilter Development Mailinglist <netfilter-devel@lists.netfilter.org>
Cc: Harald Welte <laforge@netfilter.org>
Subject: [IPTABLES PATCH] Fix leak in merge_opts
Date: Sat, 07 May 2005 16:26:08 +0200 [thread overview]
Message-ID: <427CD000.40002@eurodev.net> (raw)
[-- Attachment #1: Type: text/plain, Size: 481 bytes --]
Hi Harald,
The function merge_opts doesn't release previously merged options, this
results in a memory leak. This increases considerably memory comsumption
in iptables-restore.
This patch fixes a leak on error paths as well.
Results: With my testcase ruleset of ~10.000 rules and this patch,
iptables-restore reduces memory consumption by 66 percent. It's passed
from eating ~12 Mbytes to ~4 Mbytes. This can be interesting for
embedded devices running iptables.
--
Pablo
[-- Attachment #2: x --]
[-- Type: text/plain, Size: 2730 bytes --]
Index: iptables.c
===================================================================
--- iptables.c (revision 3889)
+++ iptables.c (working copy)
@@ -306,6 +306,16 @@
dst->s_addr = src->s_addr;
}
+static void free_opts(int reset_offset)
+{
+ if (opts != original_opts) {
+ free(opts);
+ opts = original_opts;
+ if (reset_offset)
+ global_option_offset = 0;
+ }
+}
+
void
exit_error(enum exittype status, char *msg, ...)
{
@@ -321,6 +331,8 @@
if (status == VERSION_PROBLEM)
fprintf(stderr,
"Perhaps iptables or your kernel needs to be upgraded.\n");
+ /* On error paths, make sure that we don't leak memory */
+ free_opts(1);
exit(status);
}
@@ -331,6 +343,7 @@
fprintf(stderr, "Error occurred at line: %d\n", line);
fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n",
program_name, program_name );
+ free_opts(1);
exit(status);
}
@@ -1016,6 +1029,9 @@
unsigned int num_old, num_new, i;
struct option *merge;
+ /* Release previous options merged if any */
+ free_opts(0);
+
for (num_old = 0; oldopts[num_old].name; num_old++);
for (num_new = 0; newopts[num_new].name; num_new++);
@@ -2443,12 +2459,7 @@
free(saddrs);
free(daddrs);
+ free_opts(1);
- if (opts != original_opts) {
- free(opts);
- opts = original_opts;
- global_option_offset = 0;
- }
-
return ret;
}
Index: ip6tables.c
===================================================================
--- ip6tables.c (revision 3889)
+++ ip6tables.c (working copy)
@@ -252,6 +252,16 @@
/* dst->s6_addr = src->s6_addr; */
}
+static void free_opts(int reset_offset)
+{
+ if (opts != original_opts) {
+ free(opts);
+ opts = original_opts;
+ if (reset_offset)
+ global_option_offset = 0;
+ }
+}
+
void
exit_error(enum exittype status, char *msg, ...)
{
@@ -267,6 +277,8 @@
if (status == VERSION_PROBLEM)
fprintf(stderr,
"Perhaps ip6tables or your kernel needs to be upgraded.\n");
+ /* On error paths, make sure that we don't leak memory */
+ free_opts(1);
exit(status);
}
@@ -277,6 +289,7 @@
fprintf(stderr, "Error occurred at line: %d\n", line);
fprintf(stderr, "Try `%s -h' or '%s --help' for more information.\n",
program_name, program_name );
+ free_opts(1);
exit(status);
}
@@ -1016,6 +1029,9 @@
unsigned int num_old, num_new, i;
struct option *merge;
+ /* Release previous options merged if any */
+ free_opts(0);
+
for (num_old = 0; oldopts[num_old].name; num_old++);
for (num_new = 0; newopts[num_new].name; num_new++);
@@ -2336,11 +2352,7 @@
for (c = 0; c < ndaddrs; c++)
free(&daddrs[c]);
- if (opts != original_opts) {
- free(opts);
- opts = original_opts;
- global_option_offset = 0;
- }
+ free_opts(1);
return ret;
}
next reply other threads:[~2005-05-07 14:26 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-05-07 14:26 Pablo Neira [this message]
2005-05-29 18:55 ` [IPTABLES PATCH] Fix leak in merge_opts Harald Welte
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=427CD000.40002@eurodev.net \
--to=pablo@eurodev.net \
--cc=laforge@netfilter.org \
--cc=netfilter-devel@lists.netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.