From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 57E9D38930C3; Wed, 29 Apr 2020 14:22:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 57E9D38930C3 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1588170140; bh=1DY0+XCfJeJvrbbib1FuFDCL2NVRF4IxAGuqUq/PFKg=; h=From:To:Subject:Date:From; b=OeInLwvYvBIoA/ZqGFXTR2ttcwQrtdVshtlDsXmfGt09BTOAc9szQ9g1GehrqzCWZ bf9VrugujUfpfN6qqF7rBVjtUapCwZldrf+5SFUSvCo1vg5zWFtMZXlw/GYRo4ModV NceMZ9PrCLjr/EQmPin6AZM+e/M2KZYxfEkaphzE= From: "rachel at rachelmant dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug sanitizer/94849] New: Improper parameter validation in libsanitizer for fopen64 Date: Wed, 29 Apr 2020 14:22:19 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: sanitizer X-Bugzilla-Version: 9.3.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: rachel at rachelmant dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter cc target_milestone attachments.created Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 29 Apr 2020 14:22:20 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D94849 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, marxi= n at gcc dot gnu.org Target Milestone: --- Created attachment 48408 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=3D48408&action=3Dedit A simple fix for the bug fopen() (actually fopen64 because of macro remapping) as implemented by Gli= bc 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 its= elf when this happens. Because of this, I have a test case in a project that is specifically verif= ying 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 int main() { return !fopen(nullptr, "w") ? 0 : 1; } ``` which when compiled with `g++ -D_FILE_OFFSET_BITS=3D64 -o test test.cxx` ru= ns and returns 0, but when compiled with `g++ -D_FILE_OFFSET_BITS=3D64 -o test -fsanitize=3Daddress test.cxx` or the thread sanitizer, instead crashes: ``` $ ./test; echo $? AddressSanitizer:DEADLYSIGNAL =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =3D=3D2187382=3D=3DERROR: AddressSanitizer: SEGV on unknown address 0x00000= 0000000 (pc 0x7f8867d791e5 bp 0x7ffcc8f95db0 sp 0x7ffcc8f95528 T0) =3D=3D2187382=3D=3DThe signal is caused by a READ memory access. =3D=3D2187382=3D=3DHint: 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_intercept= ors.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_a= vx2 =3D=3D2187382=3D=3DABORTING 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 a= nd 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.=