diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-07-30 03:08:51 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-07-30 03:36:52 +0200 |
commit | 2165f38d2582e88e8a9dd9416f34eca7a7672e5a (patch) | |
tree | e58c6519f8e825a9feb2367660126bdff6dbfeb1 | |
parent | f1c668268e9ddaedd8d78d7ae44cd26db1e8469f (diff) |
iptables-restore: fix parameter parsing (shows up with gcc-4.7)
This patch fixes parameter parsing 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>
-rw-r--r-- | iptables/ip6tables-restore.c | 3 | ||||
-rw-r--r-- | 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 3894d68d..1ec3dd95 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 034f9606..9f51f993 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; |