From 32b4ef6652494776c3be63721e296b08a5e37007 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Mon, 15 Jul 2024 14:25:27 -0400 Subject: [PATCH 1/3] [msan] Support prctl PR_GET_NAME call Per the man page, PR_GET_NAME stores a null terminated string into the input `char name[16]`. This also adds prctl support in ASAN to detect freed memory being passed to `prctl(PR_GET_NAME, ...)`: --- .../sanitizer_common_interceptors.inc | 14 ++++++++++- compiler-rt/test/msan/prctl.cpp | 24 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 compiler-rt/test/msan/prctl.cpp diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 1df61e79f7d84..8efde0d234088 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -1251,6 +1251,7 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); static const int PR_SET_NAME = 15; + static const int PR_GET_NAME = 16; static const int PR_SET_VMA = 0x53564d41; static const int PR_SCHED_CORE = 62; static const int PR_SCHED_CORE_GET = 0; @@ -1264,7 +1265,18 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, internal_strncpy(buff, (char *)arg2, 15); buff[15] = 0; COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); - } else if (res != -1 && option == PR_SCHED_CORE && arg2 == PR_SCHED_CORE_GET) { + } else if (res != 1 && option == PR_GET_NAME) { + unsigned long null_index = 0; + char *name = (char *)arg2; + while (null_index < 16 && name[null_index]) { + ++null_index; + } + if (null_index > 15) { + null_index = 15; + } + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)arg2, null_index + 1); + } else if (res != -1 && option == PR_SCHED_CORE && + arg2 == PR_SCHED_CORE_GET) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64*)(arg5), sizeof(u64)); } return res; diff --git a/compiler-rt/test/msan/prctl.cpp b/compiler-rt/test/msan/prctl.cpp new file mode 100644 index 0000000000000..7b8e60c98c13b --- /dev/null +++ b/compiler-rt/test/msan/prctl.cpp @@ -0,0 +1,24 @@ +// RUN: %clangxx_msan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// REQUIRES: linux + +#include +#include + +int main(void) { + prctl(PR_SET_NAME, "tname"); + char name[16]; + prctl(PR_GET_NAME, name); + + if (name[0] == 'A') { + return 0; + } + if (name[5] != '\0') { + return 0; + } + if (name[6] != '\0') { + return 0; + } + // CHECK: SUMMARY: MemorySanitizer: use-of-uninitialized-value {{.*prctl.cpp}}:[[@LINE-3]] + + return 0; +} From e33bcb723020fcf513a607e8e814e8811df1eab0 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Mon, 15 Jul 2024 23:03:55 -0400 Subject: [PATCH 2/3] Feedback; add sanitizer_common test --- .../sanitizer_common_interceptors.inc | 11 ++--------- compiler-rt/test/msan/{ => Linux}/prctl.cpp | 1 - .../test/sanitizer_common/TestCases/Linux/prctl.cpp | 10 ++++++++++ 3 files changed, 12 insertions(+), 10 deletions(-) rename compiler-rt/test/msan/{ => Linux}/prctl.cpp (95%) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 8efde0d234088..a6066a6226e1b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -1265,16 +1265,9 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, internal_strncpy(buff, (char *)arg2, 15); buff[15] = 0; COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); - } else if (res != 1 && option == PR_GET_NAME) { - unsigned long null_index = 0; + } else if (res == 0 && option == PR_GET_NAME) { char *name = (char *)arg2; - while (null_index < 16 && name[null_index]) { - ++null_index; - } - if (null_index > 15) { - null_index = 15; - } - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)arg2, null_index + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1); } else if (res != -1 && option == PR_SCHED_CORE && arg2 == PR_SCHED_CORE_GET) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64*)(arg5), sizeof(u64)); diff --git a/compiler-rt/test/msan/prctl.cpp b/compiler-rt/test/msan/Linux/prctl.cpp similarity index 95% rename from compiler-rt/test/msan/prctl.cpp rename to compiler-rt/test/msan/Linux/prctl.cpp index 7b8e60c98c13b..1af4000de8a0c 100644 --- a/compiler-rt/test/msan/prctl.cpp +++ b/compiler-rt/test/msan/Linux/prctl.cpp @@ -1,5 +1,4 @@ // RUN: %clangxx_msan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s -// REQUIRES: linux #include #include diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp index 581739500e7a9..3d51600538e6d 100644 --- 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 #include @@ -60,5 +61,14 @@ int main() { } munmap(p, 128); + res = prctl(PR_SET_NAME, "tname"); + if (res == 0) { + char name[16]; + res = prctl(PR_GET_NAME, name); + if (res == 0) { + assert(!strcmp(name, "tname")); + } + } + return 0; } From a53089f1c7804baf8d585fd57b0a6059ca378778 Mon Sep 17 00:00:00 2001 From: Chris Cotter Date: Tue, 16 Jul 2024 00:37:24 -0400 Subject: [PATCH 3/3] clang-format --- compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp index 3d51600538e6d..d5d81280e0b44 100644 --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/prctl.cpp @@ -66,7 +66,7 @@ int main() { char name[16]; res = prctl(PR_GET_NAME, name); if (res == 0) { - assert(!strcmp(name, "tname")); + assert(!strcmp(name, "tname")); } }