From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id 686EE3959CB8 for ; Mon, 8 Mar 2021 14:54:39 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 686EE3959CB8 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.cz Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mliska@suse.cz X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 52BDAADDB for ; Mon, 8 Mar 2021 14:54:38 +0000 (UTC) From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Subject: [PATCH][pushed] libsanitizer: cherry-pick ad294e572bc5c16f9dc420cc994322de6ca3fbfb To: gcc-patches@gcc.gnu.org Message-ID: <2462535b-b42b-c8af-71f9-eecdc6501ab6@suse.cz> Date: Mon, 8 Mar 2021 15:54:37 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 08 Mar 2021 14:54:41 -0000 I'm going to push one libsanitizer commit. And I'm adding a test-case for it. Martin libsanitizer/ChangeLog: PR sanitizer/98920 * asan/asan_interceptors.cpp (COMMON_INTERCEPT_FUNCTION_VER): Cherry pick. (COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK): Likewise. * asan/asan_interceptors.h (ASAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK): Likewise. * sanitizer_common/sanitizer_common_interceptors.inc (COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN): Likewise. (INIT_REGEX): Likewise. * tsan/tsan_interceptors_posix.cpp (COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK): Likewise. gcc/testsuite/ChangeLog: PR sanitizer/98920 * c-c++-common/asan/pr98920.c: New test. --- gcc/testsuite/c-c++-common/asan/pr98920.c | 24 +++++++++++++++++++ libsanitizer/asan/asan_interceptors.cpp | 5 +++- libsanitizer/asan/asan_interceptors.h | 7 ++++++ .../sanitizer_common_interceptors.inc | 19 ++++++++++++++- libsanitizer/tsan/tsan_interceptors_posix.cpp | 2 ++ 5 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/asan/pr98920.c diff --git a/gcc/testsuite/c-c++-common/asan/pr98920.c b/gcc/testsuite/c-c++-common/asan/pr98920.c new file mode 100644 index 00000000000..881d3d4901e --- /dev/null +++ b/gcc/testsuite/c-c++-common/asan/pr98920.c @@ -0,0 +1,24 @@ +/* PR sanitizer/98920 */ +/* { dg-do run } */ + +#include +#include +#include + +int main(void) +{ + regex_t r; + const char s[] = "ban\0ana"; + regmatch_t pmatch[10]; + pmatch[0].rm_so = 0; + pmatch[0].rm_eo = sizeof(s); + if (regcomp(&r, "ana", 0)) + return 2; + if (regexec(&r, s, sizeof(pmatch)/sizeof(pmatch[0]), pmatch, REG_STARTEND)) { + fprintf(stderr, "failed to match\n"); + regfree(&r); + return 3; + } + regfree(&r); + return 0; +} diff --git a/libsanitizer/asan/asan_interceptors.cpp b/libsanitizer/asan/asan_interceptors.cpp index b19cf25c7cd..4e68b3b0b47 100644 --- a/libsanitizer/asan/asan_interceptors.cpp +++ b/libsanitizer/asan/asan_interceptors.cpp @@ -90,8 +90,10 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) (void) ctx; \ #define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name) -#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ +#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ ASAN_INTERCEPT_FUNC_VER(name, ver) +#define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver) \ + ASAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver) #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ ASAN_WRITE_RANGE(ctx, ptr, size) #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ @@ -687,6 +689,7 @@ void InitializeAsanInterceptors() { // Intercept threading-related functions #if ASAN_INTERCEPT_PTHREAD_CREATE +// TODO: this should probably have an unversioned fallback for newer arches? #if defined(ASAN_PTHREAD_CREATE_VERSION) ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION); #else diff --git a/libsanitizer/asan/asan_interceptors.h b/libsanitizer/asan/asan_interceptors.h index 43cb4e3bb4f..56dc34b7d93 100644 --- a/libsanitizer/asan/asan_interceptors.h +++ b/libsanitizer/asan/asan_interceptors.h @@ -150,6 +150,13 @@ DECLARE_REAL(char*, strstr, const char *s1, const char *s2) VReport(1, "AddressSanitizer: failed to intercept '%s@@%s'\n", #name, \ #ver); \ } while (0) +#define ASAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver) \ + do { \ + if (!INTERCEPT_FUNCTION_VER(name, ver) && !INTERCEPT_FUNCTION(name)) \ + VReport(1, "AddressSanitizer: failed to intercept '%s@@%s' or '%s'\n", \ + #name, #ver, #name); \ + } while (0) + #else // OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. #define ASAN_INTERCEPT_FUNC(name) diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc index 729eead43c0..2f2787e283a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc @@ -239,6 +239,23 @@ extern const short *_tolower_tab_; COMMON_INTERCEPT_FUNCTION(fn) #endif +#ifdef __GLIBC__ +// If we could not find the versioned symbol, fall back to an unversioned +// lookup. This is needed to work around a GLibc bug that causes dlsym +// with RTLD_NEXT to return the oldest versioned symbol. +// See https://sourceware.org/bugzilla/show_bug.cgi?id=14932. +// For certain symbols (e.g. regexec) we have to perform a versioned lookup, +// but that versioned symbol will only exist for architectures where the +// oldest Glibc version pre-dates support for that architecture. +// For example, regexec@GLIBC_2.3.4 exists on x86_64, but not RISC-V. +// See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98920. +#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \ + COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(fn, ver) +#else +#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \ + COMMON_INTERCEPT_FUNCTION(fn) +#endif + #ifndef COMMON_INTERCEPTOR_MEMSET_IMPL #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \ { \ @@ -7772,7 +7789,7 @@ INTERCEPTOR(void, regfree, const void *preg) { } #define INIT_REGEX \ COMMON_INTERCEPT_FUNCTION(regcomp); \ - COMMON_INTERCEPT_FUNCTION(regexec); \ + COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(regexec, "GLIBC_2.3.4"); \ COMMON_INTERCEPT_FUNCTION(regerror); \ COMMON_INTERCEPT_FUNCTION(regfree); #else diff --git a/libsanitizer/tsan/tsan_interceptors_posix.cpp b/libsanitizer/tsan/tsan_interceptors_posix.cpp index 20c2747aaea..aa04d8dfb67 100644 --- a/libsanitizer/tsan/tsan_interceptors_posix.cpp +++ b/libsanitizer/tsan/tsan_interceptors_posix.cpp @@ -2227,6 +2227,8 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name) #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ INTERCEPT_FUNCTION_VER(name, ver) +#define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver) \ + (INTERCEPT_FUNCTION_VER(name, ver) || INTERCEPT_FUNCTION(name)) #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ MemoryAccessRange(((TsanInterceptorContext *)ctx)->thr, \ -- 2.30.1