]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
fix memory leak(s) in libiptc. Reverts the previous (wrong) patch. (Martin Josefsson)
authorMartin Josefsson <gandalf@wlug.westbo.se>
Fri, 2 May 2003 15:30:11 +0000 (15:30 +0000)
committerHarald Welte <laforge@gnumonks.org>
Fri, 2 May 2003 15:30:11 +0000 (15:30 +0000)
include/libiptc/libiptc.h
ip6tables-restore.c
ip6tables-save.c
ip6tables.c
iptables-restore.c
iptables-save.c
iptables.c
libiptc/libip4tc.c
libiptc/libip6tc.c
libiptc/libiptc.c

index 82745f93ae567aeda1ed0db2089cbd6691253304..50765d9815fe8c1221e2c5bb260963293b19d47d 100644 (file)
@@ -34,6 +34,9 @@ int iptc_is_chain(const char *chain, const iptc_handle_t handle);
 /* Take a snapshot of the rules.  Returns NULL on error. */
 iptc_handle_t iptc_init(const char *tablename);
 
+/* Cleanup after iptc_init(). */
+void iptc_free(iptc_handle_t *h);
+
 /* Iterator functions to run through the chains.  Returns NULL at end. */
 const char *iptc_first_chain(iptc_handle_t *handle);
 const char *iptc_next_chain(iptc_handle_t *handle);
index 82e1d2b0ded698048d859588693aaebeda472c3a..ecda87028f0a7e1729b4d83de1e596484c9abf40 100644 (file)
@@ -7,7 +7,7 @@
  *     Rusty Russell <rusty@linuxcare.com.au>
  * This code is distributed under the terms of GNU GPL v2
  *
- * $Id: ip6tables-restore.c,v 1.10 2002/08/14 11:40:41 laforge Exp $
+ * $Id: ip6tables-restore.c,v 1.11 2003/03/05 07:46:15 laforge Exp $
  */
 
 #include <getopt.h>
@@ -102,7 +102,7 @@ static void free_argv(void) {
 
 int main(int argc, char *argv[])
 {
-       ip6tc_handle_t handle;
+       ip6tc_handle_t handle = NULL;
        char buffer[10240];
        int c;
        char curtable[IP6T_TABLE_MAXNAMELEN + 1];
@@ -183,6 +183,9 @@ int main(int argc, char *argv[])
                        }
                        strncpy(curtable, table, IP6T_TABLE_MAXNAMELEN);
 
+                       if (handle)
+                               ip6tc_free(&handle);
+
                        handle = create_handle(table, modprobe);
                        if (noflush == 0) {
                                DEBUGP("Cleaning all chains of table '%s'\n",
index b9dbd80efd65ff48973cf0f28abc90e29d8c2c20..77cc3250e95bd64c5dc7ed33951f98ff4f902e98 100644 (file)
@@ -305,6 +305,8 @@ static int do_output(const char *tablename)
                exit_error(OTHER_PROBLEM, "Binary NYI\n");
        }
 
+       ip6tc_free(&h);
+
        return 1;
 }
 
index 17bdb4e517d8127bef371e1b8f28a42374f541cb..d250882506d78b2dafe9daaf7e04a481571cbdc2 100644 (file)
@@ -1670,6 +1670,7 @@ int do_command6(int argc, char *argv[], char **table, ip6tc_handle_t *handle)
        const char *modprobe = NULL;
        int proto_used = 0;
        char icmp6p[] = "icmpv6";
+       int no_handle = 0;
 
        memset(&fw, 0, sizeof(fw));
 
@@ -2147,8 +2148,10 @@ int do_command6(int argc, char *argv[], char **table, ip6tc_handle_t *handle)
                           chain, IP6T_FUNCTION_MAXNAMELEN);
 
        /* only allocate handle if we weren't called with a handle */
-       if (!*handle)
+       if (!*handle) {
                *handle = ip6tc_init(*table);
+               no_handle = 1;
+       }
 
        if (!*handle) {
                /* try to insmod the module if iptc_init failed */
@@ -2293,5 +2296,8 @@ int do_command6(int argc, char *argv[], char **table, ip6tc_handle_t *handle)
        if (verbose > 1)
                dump_entries6(*handle);
 
+       if (no_handle)
+               ip6tc_free(handle);
+
        return ret;
 }
index 74f7db334ac590b256cd84350a85fd55f7d96456..c1888ce5e9d41774dff2ed89b93060384fd4dc5e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * This code is distributed under the terms of GNU GPL v2
  *
- * $Id: iptables-restore.c,v 1.24 2003/03/03 08:08:37 laforge Exp $
+ * $Id: iptables-restore.c,v 1.25 2003/03/06 11:56:31 laforge Exp $
  */
 
 #include <getopt.h>
@@ -99,7 +99,7 @@ static void free_argv(void) {
 
 int main(int argc, char *argv[])
 {
-       iptc_handle_t handle;
+       iptc_handle_t handle = NULL;
        char buffer[10240];
        int c;
        char curtable[IPT_TABLE_MAXNAMELEN + 1];
@@ -180,6 +180,9 @@ int main(int argc, char *argv[])
                        }
                        strncpy(curtable, table, IPT_TABLE_MAXNAMELEN);
 
+                       if (handle)
+                               iptc_free(&handle);
+
                        handle = create_handle(table, modprobe);
                        if (noflush == 0) {
                                DEBUGP("Cleaning all chains of table '%s'\n",
index 74e71ff46d8c2b05c77e9921b1bffb0a2f6a5575..90163b501aa1c0e67e5015200879591dcd7757cf 100644 (file)
@@ -304,6 +304,8 @@ static int do_output(const char *tablename)
                exit_error(OTHER_PROBLEM, "Binary NYI\n");
        }
 
+       iptc_free(&h);
+
        return 1;
 }
 
index a3bcc78694a947708f2c3b7d4b08de2a35a32838..d181578c6ccf2cb4981d1bc3ef641b845d201c9b 100644 (file)
@@ -1668,6 +1668,7 @@ int do_command(int argc, char *argv[], char **table, iptc_handle_t *handle)
        char *protocol = NULL;
        const char *modprobe = NULL;
        int proto_used = 0;
+       int no_handle = 0;
 
        memset(&fw, 0, sizeof(fw));
 
@@ -2148,8 +2149,10 @@ int do_command(int argc, char *argv[], char **table, iptc_handle_t *handle)
                           chain, IPT_FUNCTION_MAXNAMELEN);
 
        /* only allocate handle if we weren't called with a handle */
-       if (!*handle)
+       if (!*handle) {
                *handle = iptc_init(*table);
+               no_handle = 1;
+       }
 
        if (!*handle) {
                /* try to insmod the module if iptc_init failed */
@@ -2294,5 +2297,8 @@ int do_command(int argc, char *argv[], char **table, iptc_handle_t *handle)
        if (verbose > 1)
                dump_entries(*handle);
 
+       if (no_handle)
+               iptc_free(handle);
+
        return ret;
 }
index e15df9024993bf1471738172bc4ab8215b2874d7..e012c088335bb6b43e1f81f386f483bf08a615c1 100644 (file)
@@ -91,6 +91,7 @@ typedef unsigned int socklen_t;
 #define TC_SET_POLICY          iptc_set_policy
 #define TC_GET_RAW_SOCKET      iptc_get_raw_socket
 #define TC_INIT                        iptc_init
+#define TC_FREE                        iptc_free
 #define TC_COMMIT              iptc_commit
 #define TC_STRERROR            iptc_strerror
 
index 7a88efdad21cae5101653eec180c14f5f20833da..84e139ced03c3e7ee5647005b4227d6ed9e67e0b 100644 (file)
@@ -86,6 +86,7 @@ typedef unsigned int socklen_t;
 #define TC_SET_POLICY          ip6tc_set_policy
 #define TC_GET_RAW_SOCKET      ip6tc_get_raw_socket
 #define TC_INIT                        ip6tc_init
+#define TC_FREE                        ip6tc_free
 #define TC_COMMIT              ip6tc_commit
 #define TC_STRERROR            ip6tc_strerror
 
index 55b708b8053a39871c67ddd6dfd003809821efff..fa735637b80220b50e34bd04956243aa07566dc0 100644 (file)
@@ -1,4 +1,4 @@
-/* Library which manipulates firewall rules.  Version $Revision: 1.35 $ */
+/* Library which manipulates firewall rules.  Version $Revision: 1.36 $ */
 
 /* Architecture of firewall rules is as follows:
  *
@@ -237,22 +237,26 @@ TC_INIT(const char *tablename)
        if (sockfd != -1)
                close(sockfd);
 
+       if (strlen(tablename) >= TABLE_MAXNAMELEN) {
+               errno = EINVAL;
+               return NULL;
+       }
+       
        sockfd = socket(TC_AF, SOCK_RAW, IPPROTO_RAW);
        if (sockfd < 0)
                return NULL;
 
        s = sizeof(info);
-       if (strlen(tablename) >= TABLE_MAXNAMELEN) {
-               errno = EINVAL;
-               return NULL;
-       }
+
        strcpy(info.name, tablename);
        if (getsockopt(sockfd, TC_IPPROTO, SO_GET_INFO, &info, &s) < 0)
                return NULL;
 
        if ((h = alloc_handle(info.name, info.size, info.num_entries))
-           == NULL)
+           == NULL) {
+               close(sockfd);
                return NULL;
+       }
 
 /* Too hard --RR */
 #if 0
@@ -284,6 +288,7 @@ TC_INIT(const char *tablename)
 
        if (getsockopt(sockfd, TC_IPPROTO, SO_GET_ENTRIES, &h->entries,
                       &tmp) < 0) {
+               close(sockfd);
                free(h);
                return NULL;
        }
@@ -292,6 +297,16 @@ TC_INIT(const char *tablename)
        return h;
 }
 
+void
+TC_FREE(TC_HANDLE_T *h)
+{
+       close(sockfd);
+       if ((*h)->cache_chain_heads)
+               free((*h)->cache_chain_heads);
+       free(*h);
+       *h = NULL;
+}
+
 static inline int
 print_match(const STRUCT_ENTRY_MATCH *m)
 {
@@ -504,10 +519,8 @@ TC_NEXT_CHAIN(TC_HANDLE_T *handle)
        (*handle)->cache_chain_iteration++;
 
        if ((*handle)->cache_chain_iteration - (*handle)->cache_chain_heads
-           == (*handle)->cache_num_chains) {
-               free((*handle)->cache_chain_heads);
+           == (*handle)->cache_num_chains)
                return NULL;
-       }
 
        return (*handle)->cache_chain_iteration->name;
 }
@@ -1584,11 +1597,13 @@ TC_COMMIT(TC_HANDLE_T *handle)
        STRUCT_REPLACE *repl;
        STRUCT_COUNTERS_INFO *newcounters;
        unsigned int i;
-       size_t counterlen
-               = sizeof(STRUCT_COUNTERS_INFO)
-               + sizeof(STRUCT_COUNTERS) * (*handle)->new_number;
+       size_t counterlen;
 
        CHECK(*handle);
+
+       counterlen = sizeof(STRUCT_COUNTERS_INFO)
+                       + sizeof(STRUCT_COUNTERS) * (*handle)->new_number;
+
 #if 0
        TC_DUMP_ENTRIES(*handle);
 #endif
@@ -1715,10 +1730,7 @@ TC_COMMIT(TC_HANDLE_T *handle)
        free(newcounters);
 
  finished:
-       if ((*handle)->cache_chain_heads)
-               free((*handle)->cache_chain_heads);
-       free(*handle);
-       *handle = NULL;
+       TC_FREE(handle);
        return 1;
 }