diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -1367,8 +1367,13 @@ void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); static const int PR_SET_NAME = 15; + static const int PR_SET_VMA = 1398164801; static const int PR_SCHED_CORE = 62; static const int PR_SCHED_CORE_GET = 0; + if (option == PR_SET_VMA && arg2 == 0UL) { + char *name = (char *)arg5; + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1); + } int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); if (option == PR_SET_NAME) { char buff[16]; diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #ifndef PR_SCHED_CORE @@ -17,6 +18,11 @@ # define PR_SCHED_CORE_GET 0 #endif +#ifndef PR_SET_VMA +# define PR_SET_VMA 0x53564d41 +# define PR_SET_VMA_ANON_NAME 0 +#endif + int main() { int res; @@ -34,5 +40,25 @@ assert(cookie != 0); } + char invname[81], vlname[] = "prctl"; + for (auto i = 0; i < sizeof(invname); i++) { + invname[i] = 0x1e; + } + invname[80] = 0; + auto p = + mmap(nullptr, 128, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); + assert(p != MAP_FAILED); + // regardless of kernel support, the name is invalid + res = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (uintptr_t)p, 128, + (uintptr_t)invname); + assert(res == -1); + assert(errno == EINVAL); + res = prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, (uintptr_t)p, 128, + (uintptr_t)vlname); + if (res < 0) { + assert(errno == EINVAL); + } + munmap(p, 128); + return 0; }