[msan] Support prctl PR_GET_NAME call (#98951)

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, ...)`:
This commit is contained in:
Chris Cotter
2024-07-16 12:41:41 -04:00
committed by GitHub
parent 618b0b77cd
commit 986ceae7c5
3 changed files with 39 additions and 1 deletions

View File

@@ -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,11 @@ 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 == 0 && option == PR_GET_NAME) {
char *name = (char *)arg2;
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));
}
return res;

View File

@@ -0,0 +1,23 @@
// RUN: %clangxx_msan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
#include <linux/prctl.h>
#include <sys/prctl.h>
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;
}

View File

@@ -3,6 +3,7 @@
#include <assert.h>
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
@@ -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;
}