[sanitizer] Add posix_spawn interceptor

To make pid initialized for Msan.

Reviewed By: eugenis

Differential Revision: https://reviews.llvm.org/D112784
This commit is contained in:
Vitaly Buka 2021-10-29 01:39:03 -07:00
parent 55e69ece72
commit e1240745ef
3 changed files with 90 additions and 0 deletions

View File

@ -2422,6 +2422,54 @@ INTERCEPTOR(int, glob64, const char *pattern, int flags,
#define INIT_GLOB64
#endif // SANITIZER_INTERCEPT_GLOB64
#if SANITIZER_INTERCEPT_POSIX_SPAWN
template <class RealSpawnPtr>
static int PosixSpawnImpl(void *ctx, RealSpawnPtr *real_posix_spawn, pid_t *pid,
const char *file_or_path, const void *file_actions,
const void *attrp, char *const argv[],
char *const envp[]) {
COMMON_INTERCEPTOR_READ_RANGE(ctx, file_or_path,
internal_strlen(file_or_path) + 1);
char *const *s = argv;
for (; *s; ++s)
COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
COMMON_INTERCEPTOR_READ_RANGE(ctx, argv, (s - argv + 1) / sizeof(*s));
s = envp;
for (; *s; ++s)
COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
COMMON_INTERCEPTOR_READ_RANGE(ctx, s, (s - envp + 1) / sizeof(*s));
int res =
real_posix_spawn(pid, file_or_path, file_actions, attrp, argv, envp);
if (res == 0)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pid, sizeof(*pid));
return res;
}
INTERCEPTOR(int, posix_spawn, pid_t *pid, const char *path,
const void *file_actions, const void *attrp, char *const argv[],
char *const envp[]) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, posix_spawn, pid, path, file_actions, attrp,
argv, envp);
return PosixSpawnImpl(ctx, REAL(posix_spawn), pid, path, file_actions, attrp,
argv, envp);
}
INTERCEPTOR(int, posix_spawnp, pid_t *pid, const char *file,
const void *file_actions, const void *attrp, char *const argv[],
char *const envp[]) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, posix_spawnp, pid, file, file_actions, attrp,
argv, envp);
return PosixSpawnImpl(ctx, REAL(posix_spawnp), pid, file, file_actions, attrp,
argv, envp);
}
# define INIT_POSIX_SPAWN \
COMMON_INTERCEPT_FUNCTION(posix_spawn); \
COMMON_INTERCEPT_FUNCTION(posix_spawnp);
#else // SANITIZER_INTERCEPT_POSIX_SPAWN
# define INIT_POSIX_SPAWN
#endif // SANITIZER_INTERCEPT_POSIX_SPAWN
#if SANITIZER_INTERCEPT_WAIT
// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
@ -10229,6 +10277,7 @@ static void InitializeCommonInterceptors() {
INIT_TIME;
INIT_GLOB;
INIT_GLOB64;
INIT_POSIX_SPAWN;
INIT_WAIT;
INIT_WAIT4;
INIT_INET;

View File

@ -235,6 +235,7 @@
#define SANITIZER_INTERCEPT_TIME SI_POSIX
#define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS)
#define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC
#define SANITIZER_INTERCEPT_POSIX_SPAWN SI_POSIX
#define SANITIZER_INTERCEPT_WAIT SI_POSIX
#define SANITIZER_INTERCEPT_INET SI_POSIX
#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_POSIX

View File

@ -0,0 +1,40 @@
// RUN: %clang %s -o %t && %run %t 2>&1 | FileCheck %s
#include <assert.h>
#include <spawn.h>
#include <stdio.h>
#include <wait.h>
int main(int argc, char **argv) {
if (argc > 1) {
// CHECK: SPAWNED
// CHECK: SPAWNED
printf("SPAWNED\n");
return 0;
}
int s;
posix_spawnattr_t attr;
s = posix_spawnattr_init(&attr);
assert(!s);
posix_spawn_file_actions_t file_actions;
s = posix_spawn_file_actions_init(&file_actions);
assert(!s);
char *const args[] = {argv[0], "2", NULL};
char *const env[] = {"A=B", NULL};
pid_t pid;
s = posix_spawn(&pid, argv[0], &file_actions, &attr, args, env);
assert(!s);
waitpid(pid, &s, WUNTRACED | WCONTINUED);
s = posix_spawnp(&pid, argv[0], &file_actions, &attr, args, env);
assert(!s);
waitpid(pid, &s, WUNTRACED | WCONTINUED);
return 0;
}