]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
Release previously merged options from merge_opts(), reduces memory-usage of iptables...
authorPablo Neira <pablo@eurodev.net>
Sun, 29 May 2005 19:05:23 +0000 (19:05 +0000)
committerHarald Welte <laforge@gnumonks.org>
Sun, 29 May 2005 19:05:23 +0000 (19:05 +0000)
ip6tables.c
iptables.c

index cea722920f3f2c795cf980e845220165ee47ed96..11d8cd165713a27bd86f06b080bdfcf8b60c087f 100644 (file)
@@ -252,6 +252,16 @@ in6addrcpy(struct in6_addr *dst, struct in6_addr *src)
        /* 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 @@ exit_error(enum exittype status, char *msg, ...)
        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 @@ exit_tryhelp(int status)
                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 @@ merge_options(struct option *oldopts, const struct option *newopts,
        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 @@ int do_command6(int argc, char *argv[], char **table, ip6tc_handle_t *handle)
        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;
 }
index 27c5cface2bffa3f82fa47e2e8751059203dd5bc..33ee337e6a8172b498a9c9c7461d83003e2a002d 100644 (file)
@@ -306,6 +306,16 @@ inaddrcpy(struct in_addr *dst, struct in_addr *src)
        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 @@ exit_error(enum exittype status, char *msg, ...)
        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 @@ exit_tryhelp(int status)
                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 @@ merge_options(struct option *oldopts, const struct option *newopts,
        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 @@ int do_command(int argc, char *argv[], char **table, iptc_handle_t *handle)
 
        free(saddrs);
        free(daddrs);
-
-       if (opts != original_opts) {
-               free(opts);
-               opts = original_opts;
-               global_option_offset = 0;
-       }
+       free_opts(1);
 
        return ret;
 }