libsanitizer: Intercept __makecontext_v2 on Solaris/SPARC [PR113785]

c-c++-common/asan/swapcontext-test-1.c FAILs on Solaris/SPARC:

FAIL: c-c++-common/asan/swapcontext-test-1.c   -O0  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O1  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O2 -flto  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c -O2 -flto -flto-partition=none
execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c -O3 -fomit-frame-pointer
-funroll-loops -fpeel-loops -ftracer -finline-functions execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -O3 -g  execution test
FAIL: c-c++-common/asan/swapcontext-test-1.c   -Os  execution test

As detailed in PR sanitizer/113785, this happens because an ABI change
in Solaris 10/SPARC caused the external symbol for makecontext to be
changed to __makecontext_v2, which isn't intercepted.

The following patch, submitted upstream at
https://github.com/llvm/llvm-project/pull/81588, fixes that.

Tested on sparc-sun-solaris2.11 and i386-pc-solaris2.11.

2024-02-16  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	libsanitizer:
	PR sanitizer/113785
	* asan/asan_interceptors.cpp: Cherry-pick llvm-project revision
	8c2033719a843a1880427a5e8caa5563248bce78.
This commit is contained in:
Rainer Orth 2024-02-16 14:06:24 +01:00
parent 5fd1cbfd65
commit 7c6071a66f

View file

@ -347,8 +347,16 @@ static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
PoisonShadow(bottom, ssize, 0);
}
// Since Solaris 10/SPARC, ucp->uc_stack.ss_sp refers to the stack base address
// as on other targets. For binary compatibility, the new version uses a
// different external name, so we intercept that.
# if SANITIZER_SOLARIS && defined(__sparc__)
INTERCEPTOR(void, __makecontext_v2, struct ucontext_t *ucp, void (*func)(),
int argc, ...) {
# else
INTERCEPTOR(void, makecontext, struct ucontext_t *ucp, void (*func)(), int argc,
...) {
# endif
va_list ap;
uptr args[64];
// We don't know a better way to forward ... into REAL function. We can
@ -368,7 +376,11 @@ INTERCEPTOR(void, makecontext, struct ucontext_t *ucp, void (*func)(), int argc,
ENUMERATE_ARRAY_16(0), ENUMERATE_ARRAY_16(16), ENUMERATE_ARRAY_16(32), \
ENUMERATE_ARRAY_16(48)
# if SANITIZER_SOLARIS && defined(__sparc__)
REAL(__makecontext_v2)
# else
REAL(makecontext)
# endif
((struct ucontext_t *)ucp, func, argc, ENUMERATE_ARRAY_64());
# undef ENUMERATE_ARRAY_4
@ -783,7 +795,12 @@ void InitializeAsanInterceptors() {
# if ASAN_INTERCEPT_SWAPCONTEXT
ASAN_INTERCEPT_FUNC(swapcontext);
// See the makecontext interceptor above for an explanation.
# if SANITIZER_SOLARIS && defined(__sparc__)
ASAN_INTERCEPT_FUNC(__makecontext_v2);
# else
ASAN_INTERCEPT_FUNC(makecontext);
# endif
# endif
# if ASAN_INTERCEPT__LONGJMP
ASAN_INTERCEPT_FUNC(_longjmp);