]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
iptables-restore: fix parameter parsing (shows up with gcc-4.7)
authorPablo Neira Ayuso <pablo@netfilter.org>
Mon, 30 Jul 2012 01:08:51 +0000 (03:08 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 30 Jul 2012 01:36:52 +0000 (03:36 +0200)
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>
iptables/ip6tables-restore.c
iptables/iptables-restore.c

index 3894d68d91b178e125315c14eeb177f3b9a4545d..1ec3dd958e8e5b39b9c4a2d64402ec67909fc760 100644 (file)
@@ -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;
index 034f9606a6b2605a021c66f8430fdc05ff0cbe69..9f51f993fc1104564ec2d08ec77101f8d92ed351 100644 (file)
@@ -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;