summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Josefsson <gandalf@wlug.westbo.se>2003-05-02 15:30:11 +0000
committerHarald Welte <laforge@gnumonks.org>2003-05-02 15:30:11 +0000
commit841e4aed2349046eb2c0b1375139c06569a93bd0 (patch)
tree9f7a208076fc164ca3d52e745964c7dbc7afc350
parent59cbe17cee0499c8f25a8d9f29513f4c85e9b03c (diff)
fix memory leak(s) in libiptc. Reverts the previous (wrong) patch. (Martin Josefsson)
-rw-r--r--include/libiptc/libiptc.h3
-rw-r--r--ip6tables-restore.c7
-rw-r--r--ip6tables-save.c2
-rw-r--r--ip6tables.c8
-rw-r--r--iptables-restore.c7
-rw-r--r--iptables-save.c2
-rw-r--r--iptables.c8
-rw-r--r--libiptc/libip4tc.c1
-rw-r--r--libiptc/libip6tc.c1
-rw-r--r--libiptc/libiptc.c44
10 files changed, 61 insertions, 22 deletions
diff --git a/include/libiptc/libiptc.h b/include/libiptc/libiptc.h
index 82745f93..50765d98 100644
--- a/include/libiptc/libiptc.h
+++ b/include/libiptc/libiptc.h
@@ -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);
diff --git a/ip6tables-restore.c b/ip6tables-restore.c
index 82e1d2b0..ecda8702 100644
--- a/ip6tables-restore.c
+++ b/ip6tables-restore.c
@@ -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",
diff --git a/ip6tables-save.c b/ip6tables-save.c
index b9dbd80e..77cc3250 100644
--- a/ip6tables-save.c
+++ b/ip6tables-save.c
@@ -305,6 +305,8 @@ static int do_output(const char *tablename)
exit_error(OTHER_PROBLEM, "Binary NYI\n");
}
+ ip6tc_free(&h);
+
return 1;
}
diff --git a/ip6tables.c b/ip6tables.c
index 17bdb4e5..d2508825 100644
--- a/ip6tables.c
+++ b/ip6tables.c
@@ -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;
}
diff --git a/iptables-restore.c b/iptables-restore.c
index 74f7db33..c1888ce5 100644
--- a/iptables-restore.c
+++ b/iptables-restore.c
@@ -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",
diff --git a/iptables-save.c b/iptables-save.c
index 74e71ff4..90163b50 100644
--- a/iptables-save.c
+++ b/iptables-save.c
@@ -304,6 +304,8 @@ static int do_output(const char *tablename)
exit_error(OTHER_PROBLEM, "Binary NYI\n");
}
+ iptc_free(&h);
+
return 1;
}
diff --git a/iptables.c b/iptables.c
index a3bcc786..d181578c 100644
--- a/iptables.c
+++ b/iptables.c
@@ -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;
}
diff --git a/libiptc/libip4tc.c b/libiptc/libip4tc.c
index e15df902..e012c088 100644
--- a/libiptc/libip4tc.c
+++ b/libiptc/libip4tc.c
@@ -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
diff --git a/libiptc/libip6tc.c b/libiptc/libip6tc.c
index 7a88efda..84e139ce 100644
--- a/libiptc/libip6tc.c
+++ b/libiptc/libip6tc.c
@@ -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
diff --git a/libiptc/libiptc.c b/libiptc/libiptc.c
index 55b708b8..fa735637 100644
--- a/libiptc/libiptc.c
+++ b/libiptc/libiptc.c
@@ -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;
}