mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-28 14:00:59 +08:00
libsanitizer: cherry-pick ad294e572bc5c16f9dc420cc994322de6ca3fbfb
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.
This commit is contained in:
parent
04b4828c6d
commit
81fee43851
24
gcc/testsuite/c-c++-common/asan/pr98920.c
Normal file
24
gcc/testsuite/c-c++-common/asan/pr98920.c
Normal file
@ -0,0 +1,24 @@
|
||||
/* PR sanitizer/98920 */
|
||||
/* { dg-do run } */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <regex.h>
|
||||
|
||||
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;
|
||||
}
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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, \
|
||||
|
Loading…
x
Reference in New Issue
Block a user