Skip to content

Commit e124074

Browse files
committed
[sanitizer] Add posix_spawn interceptor
To make pid initialized for Msan. Reviewed By: eugenis Differential Revision: https://reviews.llvm.org/D112784
1 parent 55e69ec commit e124074

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2422,6 +2422,54 @@ INTERCEPTOR(int, glob64, const char *pattern, int flags,
24222422
#define INIT_GLOB64
24232423
#endif // SANITIZER_INTERCEPT_GLOB64
24242424

2425+
#if SANITIZER_INTERCEPT_POSIX_SPAWN
2426+
2427+
template <class RealSpawnPtr>
2428+
static int PosixSpawnImpl(void *ctx, RealSpawnPtr *real_posix_spawn, pid_t *pid,
2429+
const char *file_or_path, const void *file_actions,
2430+
const void *attrp, char *const argv[],
2431+
char *const envp[]) {
2432+
COMMON_INTERCEPTOR_READ_RANGE(ctx, file_or_path,
2433+
internal_strlen(file_or_path) + 1);
2434+
char *const *s = argv;
2435+
for (; *s; ++s)
2436+
COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
2437+
COMMON_INTERCEPTOR_READ_RANGE(ctx, argv, (s - argv + 1) / sizeof(*s));
2438+
s = envp;
2439+
for (; *s; ++s)
2440+
COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
2441+
COMMON_INTERCEPTOR_READ_RANGE(ctx, s, (s - envp + 1) / sizeof(*s));
2442+
int res =
2443+
real_posix_spawn(pid, file_or_path, file_actions, attrp, argv, envp);
2444+
if (res == 0)
2445+
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pid, sizeof(*pid));
2446+
return res;
2447+
}
2448+
INTERCEPTOR(int, posix_spawn, pid_t *pid, const char *path,
2449+
const void *file_actions, const void *attrp, char *const argv[],
2450+
char *const envp[]) {
2451+
void *ctx;
2452+
COMMON_INTERCEPTOR_ENTER(ctx, posix_spawn, pid, path, file_actions, attrp,
2453+
argv, envp);
2454+
return PosixSpawnImpl(ctx, REAL(posix_spawn), pid, path, file_actions, attrp,
2455+
argv, envp);
2456+
}
2457+
INTERCEPTOR(int, posix_spawnp, pid_t *pid, const char *file,
2458+
const void *file_actions, const void *attrp, char *const argv[],
2459+
char *const envp[]) {
2460+
void *ctx;
2461+
COMMON_INTERCEPTOR_ENTER(ctx, posix_spawnp, pid, file, file_actions, attrp,
2462+
argv, envp);
2463+
return PosixSpawnImpl(ctx, REAL(posix_spawnp), pid, file, file_actions, attrp,
2464+
argv, envp);
2465+
}
2466+
# define INIT_POSIX_SPAWN \
2467+
COMMON_INTERCEPT_FUNCTION(posix_spawn); \
2468+
COMMON_INTERCEPT_FUNCTION(posix_spawnp);
2469+
#else // SANITIZER_INTERCEPT_POSIX_SPAWN
2470+
# define INIT_POSIX_SPAWN
2471+
#endif // SANITIZER_INTERCEPT_POSIX_SPAWN
2472+
24252473
#if SANITIZER_INTERCEPT_WAIT
24262474
// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
24272475
// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
@@ -10229,6 +10277,7 @@ static void InitializeCommonInterceptors() {
1022910277
INIT_TIME;
1023010278
INIT_GLOB;
1023110279
INIT_GLOB64;
10280+
INIT_POSIX_SPAWN;
1023210281
INIT_WAIT;
1023310282
INIT_WAIT4;
1023410283
INIT_INET;

compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@
235235
#define SANITIZER_INTERCEPT_TIME SI_POSIX
236236
#define SANITIZER_INTERCEPT_GLOB (SI_GLIBC || SI_SOLARIS)
237237
#define SANITIZER_INTERCEPT_GLOB64 SI_GLIBC
238+
#define SANITIZER_INTERCEPT_POSIX_SPAWN SI_POSIX
238239
#define SANITIZER_INTERCEPT_WAIT SI_POSIX
239240
#define SANITIZER_INTERCEPT_INET SI_POSIX
240241
#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_POSIX
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %clang %s -o %t && %run %t 2>&1 | FileCheck %s
2+
3+
#include <assert.h>
4+
#include <spawn.h>
5+
#include <stdio.h>
6+
#include <wait.h>
7+
8+
int main(int argc, char **argv) {
9+
if (argc > 1) {
10+
// CHECK: SPAWNED
11+
// CHECK: SPAWNED
12+
printf("SPAWNED\n");
13+
return 0;
14+
}
15+
16+
int s;
17+
18+
posix_spawnattr_t attr;
19+
s = posix_spawnattr_init(&attr);
20+
assert(!s);
21+
22+
posix_spawn_file_actions_t file_actions;
23+
s = posix_spawn_file_actions_init(&file_actions);
24+
assert(!s);
25+
26+
char *const args[] = {argv[0], "2", NULL};
27+
char *const env[] = {"A=B", NULL};
28+
29+
pid_t pid;
30+
s = posix_spawn(&pid, argv[0], &file_actions, &attr, args, env);
31+
assert(!s);
32+
33+
waitpid(pid, &s, WUNTRACED | WCONTINUED);
34+
35+
s = posix_spawnp(&pid, argv[0], &file_actions, &attr, args, env);
36+
assert(!s);
37+
38+
waitpid(pid, &s, WUNTRACED | WCONTINUED);
39+
return 0;
40+
}

0 commit comments

Comments
 (0)