This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug c/48916] New: Falsely reported buffer overrun due to incorrect __builtin_object_size.


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

           Summary: Falsely reported buffer overrun due to incorrect
                    __builtin_object_size.
           Product: gcc
           Version: 4.5.2
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: jkb@sanger.ac.uk


Created attachment 24199
  --> http://gcc.gnu.org/bugzilla/attachment.cgi?id=24199
Demonstration of failure for -O -D_FORTIFY_SOURCE=2

I have a case where __builtin_object_size() appears to return an incorrect
value (1), causing strcpy when used under -D_FORTIFY_SOURCE=2 to claim a buffer
overrun has been detected.

We allocate a block of memory sufficiently large to hold both a structure and a
string immediately following it. The structure holds a pointer to this string
and, for ease of programming, a terminal member whose address will be the start
of the string. An example:

typedef struct {
    char *name;  // == &foo.data
    char data;   // Note: vs char data[], char data[1] or char data[0]
} foo_t;

In this situation, __bos(foo->name) is neither -1 nor is it the correct size.
Instead it appears to be the space remaining up to the end of the structure
rather than up to the end of the malloced block of memory.

More oddly is that only the first call to __builtin_object_size returns a value
while all subsequent calls return -1 instead. This is the primary reason I
suspect this to be a compiler bug rather than simply allowably undefined
behaviour, as we would expect a consistent result.

The error is easily worked around (from a coder's point of view) by changing
the terminal "char data" member to the C99 recommended "char data[]", the prior
GCC equivalent "char data[0]" or even "char data[1]" (which I'd assume to be
identical in behaviour to "char data").

Note that I am unsure of whether this sneaky practice is strictly conforming to
the C standard when not using data[] or data[0], as it means writing to
&foo->data will be performing pointer arithmetic which starts within the struct
and ends up outside of the struct, albeit still within the same malloc heap
element. If it is non-standard, then this may simply fall into the realm of
"undefined behaviour".

The issue was initially discovered using Gentoo-11 with gcc 4.5.2, but has
since been verified as failing on 4.4.4-10.fc13 (Red Hat's patched-
for-Fedora version), 4.5.0, 4.5.2, 4.5.3, and 4.6.0. It works on 4.4.3 and
earlier.

It seems likely the implementation (specifically the non-constant result) of
__builtin_object_size() is the issue. Sorry I do not know if this consistutes
front-end or middle; please update the component as required.

Attached is a program to demonstrate the issue.

James


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]