[Bug c/53424] New: dynamic array expressions get wrong sizeof() if pointers to const are involved and the pointers are changed (const is misapplied to the whole expression)

gccbug at shaggy dot cc gcc-bugzilla@gcc.gnu.org
Sun May 20 09:11:00 GMT 2012


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53424

             Bug #: 53424
           Summary: dynamic array expressions get wrong sizeof() if
                    pointers to const are involved and the pointers are
                    changed (const is misapplied to the whole expression)
    Classification: Unclassified
           Product: gcc
           Version: 4.6.3
            Status: UNCONFIRMED
          Severity: major
          Priority: P3
         Component: c
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: gccbug@shaggy.cc


Created attachment 27448
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=27448
compile with -std=c99, optimization on or off

If a dynamic array on the stack is declared using an expression with a pointer
to const, as follows:

int y[2] = {10,20};
const int *x = y;
char buf[*x];

Then changing x (which is valid, since it is *x that is const, not x), as
follows:
++x;

results in sizeof(buf) being something quite different than the size it was
originally created.

Removing the const makes it work as one would expect.

Changing sizeof(buf) after the buffer is allocated on the stack is a very
dangerous thing.  If this pattern using expressions with const to initialize
the array is known to be in any code, it could probably be exploited to get
access to the stack, and thus could be a security concern.

The attached code generates pairs of functions that ought to be identical.  The
only difference is the "const".  The "works()" and "broken()" functions should
both return 10.   The "crashes()" and "nocrash()" functions should both assign
to the last byte of the array on the stack (index 9), but the crashing one
tries to assign it far beyond those bounds, using the 3rd element of array y
just because x got moved.

The const is being misapplied to treat the entire array initializer as a
constant expression, so the compiler appears to think it can simply re-evaluate
the expression as needed to get sizeof(buf), even though the pointer in the
expression has been changed.

The older gcc-4.2.1 LLVM compilers (Mac) I tried it on have the same bug.



More information about the Gcc-bugs mailing list