From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1734) id D72E0385B521; Thu, 26 Jan 2023 18:39:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D72E0385B521 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1674758376; bh=rb+fgiIwknZZEu9YOFpyTtiodFzWt85691hncvtsWFw=; h=From:To:Subject:Date:From; b=gHeNKVPqcBZJ4RceG1/nIBd0OfdE/6C+L1+44j3sWNNVTjFmb6Lyl6Aw4UbNbRjGh qfO2JPnMZPM53eVW5mhwKZCWNmyFmKuWli20N+LGuPLDgrmyd3jYCpnIVefM4Lw+Bq WtbeanLywzxkC4Yys4+KhfgNbkU080v5jSa6d5q0= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Marek Polacek To: gcc-cvs@gcc.gnu.org Subject: [gcc r12-9071] opts: SANITIZE_ADDRESS wrongly cleared [PR108543] X-Act-Checkin: gcc X-Git-Author: Marek Polacek X-Git-Refname: refs/heads/releases/gcc-12 X-Git-Oldrev: 96cf4658b2d97251602f6865b18329ff72ee8228 X-Git-Newrev: 786923f74d6adfaf572f3d7c0307c51c522567f9 Message-Id: <20230126183936.D72E0385B521@sourceware.org> Date: Thu, 26 Jan 2023 18:39:36 +0000 (GMT) List-Id: https://gcc.gnu.org/g:786923f74d6adfaf572f3d7c0307c51c522567f9 commit r12-9071-g786923f74d6adfaf572f3d7c0307c51c522567f9 Author: Marek Polacek Date: Wed Jan 25 17:19:54 2023 -0500 opts: SANITIZE_ADDRESS wrongly cleared [PR108543] Here we crash on a null fndecl ultimately because we haven't defined the built-ins described in sanitizer.def. So builtin_decl_explicit (BUILT_IN_ASAN_POINTER_SUBTRACT); returns NULL_TREE, causing an ICE later. DEF_SANITIZER_BUILTIN only actually defines the built-ins when flag_sanitize has SANITIZE_ADDRESS, or some of the other SANITIZE_*, but it doesn't check SANITIZE_KERNEL_ADDRESS or SANITIZE_USER_ADDRESS. Unfortunately, with -fsanitize=address -fno-sanitize=kernel-address or -fsanitize=kernel-address -fno-sanitize=address SANITIZE_ADDRESS ends up being unset from flag_sanitize even though _USER/_KERNEL are set. That's because -fsanitize=address means SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS and -fsanitize=kernel-address is SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS but parse_sanitizer_options does flags &= ~sanitizer_opts[i].flag; so the subsequent -fno- unsets SANITIZE_ADDRESS. Then no sanitizer built-ins are actually defined. I'm not sure why SANITIZE_ADDRESS isn't just SANITIZE_USER_ADDRESS | SANITIZE_KERNEL_ADDRESS, I don't think we need 3 bits. PR middle-end/108543 gcc/ChangeLog: * opts.cc (parse_sanitizer_options): Don't always clear SANITIZE_ADDRESS if it was previously set. gcc/testsuite/ChangeLog: * c-c++-common/asan/pointer-subtract-5.c: New test. * c-c++-common/asan/pointer-subtract-6.c: New test. * c-c++-common/asan/pointer-subtract-7.c: New test. * c-c++-common/asan/pointer-subtract-8.c: New test. (cherry picked from commit a82ce9c8d155ecda2d1c647d5c588f29e21ef4a3) Diff: --- gcc/opts.cc | 9 ++++++++- gcc/testsuite/c-c++-common/asan/pointer-subtract-5.c | 15 +++++++++++++++ gcc/testsuite/c-c++-common/asan/pointer-subtract-6.c | 15 +++++++++++++++ gcc/testsuite/c-c++-common/asan/pointer-subtract-7.c | 15 +++++++++++++++ gcc/testsuite/c-c++-common/asan/pointer-subtract-8.c | 15 +++++++++++++++ 5 files changed, 68 insertions(+), 1 deletion(-) diff --git a/gcc/opts.cc b/gcc/opts.cc index 3a89da2dd03..a97630d1c9a 100644 --- a/gcc/opts.cc +++ b/gcc/opts.cc @@ -2201,7 +2201,14 @@ parse_sanitizer_options (const char *p, location_t loc, int scode, flags |= sanitizer_opts[i].flag; } else - flags &= ~sanitizer_opts[i].flag; + { + flags &= ~sanitizer_opts[i].flag; + /* Don't always clear SANITIZE_ADDRESS if it was previously + set: -fsanitize=address -fno-sanitize=kernel-address should + leave SANITIZE_ADDRESS set. */ + if (flags & (SANITIZE_KERNEL_ADDRESS | SANITIZE_USER_ADDRESS)) + flags |= SANITIZE_ADDRESS; + } found = true; break; } diff --git a/gcc/testsuite/c-c++-common/asan/pointer-subtract-5.c b/gcc/testsuite/c-c++-common/asan/pointer-subtract-5.c new file mode 100644 index 00000000000..867eda0e61e --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pointer-subtract-5.c @@ -0,0 +1,15 @@ +/* PR middle-end/108543 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=address -fno-sanitize=kernel-address -fsanitize=pointer-subtract" } */ + +struct S { + long _M_p; +}; + +typedef struct S S; + +__PTRDIFF_TYPE__ +f (S __x, S __y) +{ + return &__x._M_p - &__y._M_p; +} diff --git a/gcc/testsuite/c-c++-common/asan/pointer-subtract-6.c b/gcc/testsuite/c-c++-common/asan/pointer-subtract-6.c new file mode 100644 index 00000000000..785b90b3d98 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pointer-subtract-6.c @@ -0,0 +1,15 @@ +/* PR middle-end/108543 */ +/* { dg-do compile } */ +/* { dg-options "-fsanitize=kernel-address -fno-sanitize=address -fsanitize=pointer-subtract" } */ + +struct S { + long _M_p; +}; + +typedef struct S S; + +__PTRDIFF_TYPE__ +f (S __x, S __y) +{ + return &__x._M_p - &__y._M_p; +} diff --git a/gcc/testsuite/c-c++-common/asan/pointer-subtract-7.c b/gcc/testsuite/c-c++-common/asan/pointer-subtract-7.c new file mode 100644 index 00000000000..11b63401b8c --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pointer-subtract-7.c @@ -0,0 +1,15 @@ +/* PR middle-end/108543 */ +/* { dg-do compile } */ +/* { dg-options "-fno-sanitize=kernel-address -fsanitize=address -fsanitize=pointer-subtract" } */ + +struct S { + long _M_p; +}; + +typedef struct S S; + +__PTRDIFF_TYPE__ +f (S __x, S __y) +{ + return &__x._M_p - &__y._M_p; +} diff --git a/gcc/testsuite/c-c++-common/asan/pointer-subtract-8.c b/gcc/testsuite/c-c++-common/asan/pointer-subtract-8.c new file mode 100644 index 00000000000..ac2b9c3c1d9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pointer-subtract-8.c @@ -0,0 +1,15 @@ +/* PR middle-end/108543 */ +/* { dg-do compile } */ +/* { dg-options "-fno-sanitize=address -fsanitize=kernel-address -fsanitize=pointer-subtract" } */ + +struct S { + long _M_p; +}; + +typedef struct S S; + +__PTRDIFF_TYPE__ +f (S __x, S __y) +{ + return &__x._M_p - &__y._M_p; +}