public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug sanitizer/94849] New: Improper parameter validation in libsanitizer for fopen64
@ 2020-04-29 14:22 rachel at rachelmant dot com
  2020-04-29 14:28 ` [Bug sanitizer/94849] " marxin at gcc dot gnu.org
                   ` (8 more replies)
  0 siblings, 9 replies; 10+ messages in thread
From: rachel at rachelmant dot com @ 2020-04-29 14:22 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94849

            Bug ID: 94849
           Summary: Improper parameter validation in libsanitizer for
                    fopen64
           Product: gcc
           Version: 9.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rachel at rachelmant dot com
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org
  Target Milestone: ---

Created attachment 48408
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48408&action=edit
A simple fix for the bug

fopen() (actually fopen64 because of macro remapping) as implemented by Glibc
and other C run-times allows the first "path" or "filename" parameter to be
nullptr and causes the function to simply do nothing and return nullptr itself
when this happens.

Because of this, I have a test case in a project that is specifically verifying
this bad, but allowed, use of fopen64() as a way to guarantee it returns
nullptr for some further tests and for code coverage reasons.

The simplest form of failing program is:

```
#include <cstdio>

int main()
{
    return !fopen(nullptr, "w") ? 0 : 1;
}
```

which when compiled with `g++ -D_FILE_OFFSET_BITS=64 -o test test.cxx` runs and
returns 0, but when compiled with `g++ -D_FILE_OFFSET_BITS=64 -o test
-fsanitize=address test.cxx` or the thread sanitizer, instead crashes:

```
$ ./test; echo $?
AddressSanitizer:DEADLYSIGNAL
=================================================================
==2187382==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc
0x7f8867d791e5 bp 0x7ffcc8f95db0 sp 0x7ffcc8f95528 T0)
==2187382==The signal is caused by a READ memory access.
==2187382==Hint: address points to the zero page.
    #0 0x7f8867d791e4 in __strlen_avx2 (/usr/lib/libc.so.6+0x1611e4)
    #1 0x7f886817cc35 in __interceptor_fopen64
/build/gcc/src/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:5757
    #2 0x56367982918d in main (/tmp/test+0x118d)
    #3 0x7f8867c3f022 in __libc_start_main (/usr/lib/libc.so.6+0x27022)
    #4 0x5636798290ad in _start (/tmp/test+0x10ad)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (/usr/lib/libc.so.6+0x1611e4) in __strlen_avx2
==2187382==ABORTING
1

```

This is on GCC 9.3.0, but I have reproduced this on everything from GCC 5
through to 9. Please note: This is not a problem when the non-64-bit fopen() is
used. This is specifically a problem with fopen64().

Unfortunately, libsanitizer does not properly validate the path parameter and
ends up calling strlen() on a nullptr - which is UB that on x86 crashes with
SEGV as seen above.

After triggering the bug and doing some research, it appears that since the
introduction of libsanitizer, this has been a thing:
https://github.com/gcc-mirror/gcc/blob/master/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc#L5882

Attached is a patch that would fix this bugged behaviour.

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-05-04 18:12 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-29 14:22 [Bug sanitizer/94849] New: Improper parameter validation in libsanitizer for fopen64 rachel at rachelmant dot com
2020-04-29 14:28 ` [Bug sanitizer/94849] " marxin at gcc dot gnu.org
2020-04-29 14:30 ` jakub at gcc dot gnu.org
2020-04-29 14:33 ` marxin at gcc dot gnu.org
2020-04-29 14:38 ` rachel at rachelmant dot com
2020-04-29 14:53 ` jakub at gcc dot gnu.org
2020-04-29 15:03 ` rachel at rachelmant dot com
2020-04-29 15:52 ` rachel at rachelmant dot com
2020-04-30 19:03 ` msebor at gcc dot gnu.org
2020-05-04 18:12 ` marxin at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).