tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Use of uninitalized automatic variable in TCC when p


From: Pascal Cuoq
Subject: Re: [Tinycc-devel] Use of uninitalized automatic variable in TCC when parsing “int f ( int ( )”
Date: Sun, 10 Mar 2019 00:42:17 +0000

Finally, adding one more bit of instrumentation shows that TCC can crash because of the uninitialized variable being discussed in this thread.

On 08 Mar 2019, at 20:06, Pascal Cuoq <address@hidden> wrote:

the simplest way to make this problem visible is to instrument the functions type_decl and post_type:

diff --git a/tccgen.c b/tccgen.c
index 87ec798..7fa6c72 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -4374,7 +4374,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
     Sym **plast, *s, *first;
     AttributeDef ad1;
     CType pt;
-
+    n = 0xf00f0011;
     if (tok == '(') {
         /* function type, or recursive declarator (return if so) */
         next();
@@ -4410,6 +4410,7 @@ static int post_type(CType *type, AttributeDef *ad, int storage, int td)
                 }
                 convert_parameter_type(&pt);
                 arg_size += (type_size(&pt, &align) + PTR_SIZE - 1) / PTR_SIZE;
+                if (n == 0xf00f0011) printf("using n uninitialized\n");
                 s = sym_push(n | SYM_FIELD, &pt, 0, 0);
                 *plast = s;
                 plast = &s->next;
@@ -4583,7 +4584,7 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
            parse_attribute(ad);
            post = type_decl(type, ad, v, td);
            skip(')');
-       }
+       } else printf("*v left uninitialized\n");
     } else if (tok >= TOK_IDENT && (td & TYPE_DIRECT)) {
        /* type identifier */
        *v = tok;


The function post_type declares an automatic variable n and does not initialize it. Setting it to 0xf00f0011 allows to see that it has not been assigned when it is used later in this function (ored with SYM_FIELD and passed as argument to the function sym_push). When “using n uninitialized” is printed in the instrumented version of TCC, it means that n would have been used uninitialized in the uninstrumented version of the compiler.

To understand the crash, add the following patch to the instrumentation that was already discussed:

diff --git a/tccgen.c b/tccgen.c
index 87ec798..ee5a838 100644
--- a/tccgen.c
+++ b/tccgen.c
@@ -588,6 +588,10 @@ ST_FUNC Sym *sym_push(int v, CType *type, int r, int c)
     /* XXX: simplify */
     if (!(v & SYM_FIELD) && (v & ~SYM_STRUCT) < SYM_FIRST_ANOM) {
         /* record symbol in token array */
+        if (v == 0xd00f0011) {
+          printf("v < 0, this will not go well\n");
+          fflush(stdout);
+        }
         ts = table_ident[(v & ~SYM_STRUCT) - TOK_IDENT];
         if (v & SYM_STRUCT)
             ps = &ts->sym_struct;


This patch shows that the value 0xf00f0011, that was been chosen as the value of the uninitialized variable n in the function type_decl, can for some inputs be propagated until it is used to compute an address.

$ cat c.i
int f(int ()) {
  return 0;
}
$ ./tcc -c c.i
*v left uninitialized
using n uninitialized
v < 0, this will not go well
Segmentation fault

The crash may be more difficult to observe without the first part of the instrumentation, but regardless the root cause for it, when it happens, is the fact that the automatic variable n from the function type_decl is sometimes incorporated into computations without having been set beforehand.

Pascal


reply via email to

[Prev in Thread] Current Thread [Next in Thread]