• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1From fb63f8b7337aa11a667537e6a3b399062ede2eb5 Mon Sep 17 00:00:00 2001
2From: Phil Sutter <phil@nwl.cc>
3Date: Fri, 25 Nov 2022 21:35:28 +0100
4Subject: [PATCH] iptables: Plug memleaks in print_firewall()
5
6When adding a rule in verbose mode, valgrind prints:
7
8192 bytes in 1 blocks are definitely lost in loss record 1 of 2
9   at 0x48417E5: malloc (vg_replace_malloc.c:381)
10   by 0x486B158: xtables_malloc (xtables.c:446)
11   by 0x486C1F6: xtables_find_match (xtables.c:826)
12   by 0x10E684: print_match (iptables.c:115)
13   by 0x10E684: print_firewall (iptables.c:169)
14   by 0x10FC0C: print_firewall_line (iptables.c:196)
15   by 0x10FC0C: append_entry (iptables.c:221)
16   by 0x10FC0C: do_command4 (iptables.c:776)
17   by 0x10E45B: iptables_main (iptables-standalone.c:59)
18   by 0x49A2349: (below main) (in /lib64/libc.so.6)
19
20200 bytes in 1 blocks are definitely lost in loss record 2 of 2
21   at 0x48417E5: malloc (vg_replace_malloc.c:381)
22   by 0x486B158: xtables_malloc (xtables.c:446)
23   by 0x486BBD6: xtables_find_target (xtables.c:956)
24   by 0x10E579: print_firewall (iptables.c:145)
25   by 0x10FC0C: print_firewall_line (iptables.c:196)
26   by 0x10FC0C: append_entry (iptables.c:221)
27   by 0x10FC0C: do_command4 (iptables.c:776)
28   by 0x10E45B: iptables_main (iptables-standalone.c:59)
29   by 0x49A2349: (below main) (in /lib64/libc.so.6)
30
31If the match/target was cloned, it needs to be freed. Basically a bug since
32day 1.
33
34Conflict: NA
35Reference: https://git.netfilter.org/iptables/commit?id=fb63f8b7337aa11a667537e6a3b399062ede2eb5
36
37Signed-off-by: Phil Sutter <phil@nwl.cc>
38---
39 iptables/ip6tables.c | 6 ++++++
40 iptables/iptables.c  | 6 ++++++
41 2 files changed, 12 insertions(+)
42
43diff --git a/iptables/ip6tables.c b/iptables/ip6tables.c
44index 062b2b15..1d232657 100644
45--- a/iptables/ip6tables.c
46+++ b/iptables/ip6tables.c
47@@ -122,6 +122,9 @@ print_match(const struct xt_entry_match *m,
48 			printf("%s%s ", match->name, unsupported_rev);
49 		else
50 			printf("%s ", match->name);
51+
52+		if (match->next == match)
53+			free(match);
54 	} else {
55 		if (name[0])
56 			printf("UNKNOWN match `%s' ", name);
57@@ -179,6 +182,9 @@ print_firewall(const struct ip6t_entry *fw,
58 			tg->print(&fw->ipv6, t, format & FMT_NUMERIC);
59 		else if (target->print)
60 			printf(" %s%s", target->name, unsupported_rev);
61+
62+		if (target->next == target)
63+			free(target);
64 	} else if (t->u.target_size != sizeof(*t))
65 		printf("[%u bytes of unknown target data] ",
66 		       (unsigned int)(t->u.target_size - sizeof(*t)));
67diff --git a/iptables/iptables.c b/iptables/iptables.c
68index 0351b39f..d246198f 100644
69--- a/iptables/iptables.c
70+++ b/iptables/iptables.c
71@@ -122,6 +122,9 @@ print_match(const struct xt_entry_match *m,
72 			printf("%s%s ", match->name, unsupported_rev);
73 		else
74 			printf("%s ", match->name);
75+
76+		if (match->next == match)
77+			free(match);
78 	} else {
79 		if (name[0])
80 			printf("UNKNOWN match `%s' ", name);
81@@ -178,6 +181,9 @@ print_firewall(const struct ipt_entry *fw,
82 			tg->print(&fw->ip, t, format & FMT_NUMERIC);
83 		else if (target->print)
84 			printf(" %s%s", target->name, unsupported_rev);
85+
86+		if (target->next == target)
87+			free(target);
88 	} else if (t->u.target_size != sizeof(*t))
89 		printf("[%u bytes of unknown target data] ",
90 		       (unsigned int)(t->u.target_size - sizeof(*t)));
91--
922.23.0
93