Message ID | 20120730013707.GA2350@1984 |
---|---|
State | Not Applicable |
Headers | show |
On Mon, Jul 30, 2012 at 03:37:07AM +0200, Pablo Neira Ayuso wrote: > From 8cfcb0137f4aee880ec749cd2356148325f6085d Mon Sep 17 00:00:00 2001 > From: Pablo Neira Ayuso <pablo@netfilter.org> > Date: Mon, 30 Jul 2012 03:08:51 +0200 > Subject: [PATCH] iptables-restore: fix memory corruption in parameter parsing > with gcc-4.7 I'm going to change the title of this patch, memory corruption does not seem appropriate. Instead, the problem seems to be related to wrong assumptions on uninitialized memory area. -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Monday 2012-07-30 03:37, Pablo Neira Ayuso wrote: >> > // here param_buffer[1024] is lost, so any var pointing >> > // to it can mess stack >> > >> > previous gcc were probably not so aggressive. >> >> Oh well, add_argv() does a strdup(), so iptables code seems fine. > >I thought the same, but one contributor has put some on light on this. > >I'm going to revert the patch that I applied to fix this and apply >the one that comes with this email instead. > >It contains a simple description of the problem, I think it's good for >the record (distro maintainers will likely google for this). Your code cleanup, by moving the code into a separate function, is however still desired :) -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Aug 02, 2012 at 09:37:10PM +0200, Jan Engelhardt wrote: > > On Monday 2012-07-30 03:37, Pablo Neira Ayuso wrote: > >> > // here param_buffer[1024] is lost, so any var pointing > >> > // to it can mess stack > >> > > >> > previous gcc were probably not so aggressive. > >> > >> Oh well, add_argv() does a strdup(), so iptables code seems fine. > > > >I thought the same, but one contributor has put some on light on this. > > > >I'm going to revert the patch that I applied to fix this and apply > >the one that comes with this email instead. > > > >It contains a simple description of the problem, I think it's good for > >the record (distro maintainers will likely google for this). > > Your code cleanup, by moving the code into a separate function, > is however still desired :) OK, it's back: http://git.netfilter.org/cgi-bin/gitweb.cgi?p=iptables.git;a=commit;h=23a98b56935c42ef460020e37a9ff8006eee58e2 -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
From 8cfcb0137f4aee880ec749cd2356148325f6085d Mon Sep 17 00:00:00 2001 From: Pablo Neira Ayuso <pablo@netfilter.org> Date: Mon, 30 Jul 2012 03:08:51 +0200 Subject: [PATCH] iptables-restore: fix memory corruption in parameter parsing with gcc-4.7 This patch fixes a memory corruption that has been in iptables-restore since time ago. The problem has shown up with gcc-4.7. This version of gcc seem to perform more agressive memory management than previous. Peter Lekensteyn provided the following sample code similar to the one in iptables-restore: int i = 0; for (;;) { char x[5]; x[i] = '0' + i; if (++i == 4) { x[i] = '\0'; /* terminate string with null byte */ printf("%s\n", x); break; } } Many may expect 0123 as output. But GCC 4.7 does not do that when compiling with optimization enabled (-O1 and higher). It instead puts random data in the first bytes of the character array, which becomes: | 0 | 1 | 2 | 3 | 4 | | RANDOM | '3' | '\0' | Since the array is declared inside the scope of loop's body, you can think of it as of a new array being allocated in the automatic storage area for each loop iteration. The correct code should be: char x[5]; for (;;) { x[i] = '0' + i; if (++i == 4) { x[i] = '\0'; /* terminate string with null byte */ printf("%s\n", x); break; } } Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org> --- iptables/ip6tables-restore.c | 3 +-- iptables/iptables-restore.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/iptables/ip6tables-restore.c b/iptables/ip6tables-restore.c index 3894d68..1ec3dd9 100644 --- a/iptables/ip6tables-restore.c +++ b/iptables/ip6tables-restore.c @@ -329,6 +329,7 @@ int ip6tables_restore_main(int argc, char *argv[]) char *curchar; int quote_open, escaped; size_t param_len; + char param_buffer[1024]; /* reset the newargv */ newargc = 0; @@ -379,8 +380,6 @@ int ip6tables_restore_main(int argc, char *argv[]) param_len = 0; for (curchar = parsestart; *curchar; curchar++) { - char param_buffer[1024]; - if (quote_open) { if (escaped) { param_buffer[param_len++] = *curchar; diff --git a/iptables/iptables-restore.c b/iptables/iptables-restore.c index 034f960..9f51f99 100644 --- a/iptables/iptables-restore.c +++ b/iptables/iptables-restore.c @@ -329,6 +329,7 @@ iptables_restore_main(int argc, char *argv[]) char *curchar; int quote_open, escaped; size_t param_len; + char param_buffer[1024]; /* reset the newargv */ newargc = 0; @@ -379,8 +380,6 @@ iptables_restore_main(int argc, char *argv[]) param_len = 0; for (curchar = parsestart; *curchar; curchar++) { - char param_buffer[1024]; - if (quote_open) { if (escaped) { param_buffer[param_len++] = *curchar; -- 1.7.10.4