Skip to content

Commit

Permalink
[sanitizer_common] Implement popen, popenve, pclose interceptors
Browse files Browse the repository at this point in the history
Implement the interceptors for popen(), pclose() and popenve()
functions.  The first two are POSIX, the third one is specific
to NetBSD.  popen() spawns a process and creates a FILE object piping
data from/to that process.  pclose() closes the pipe and waits for
the process to terminate appropriately.

For the purpose of popen(), the COMMON_INTERCEPTOR_FILE_OPEN macro is
modified to allow null path parameter.

Differential Revision: https://reviews.llvm.org/D56157

llvm-svn: 350232
  • Loading branch information
mgorny committed Jan 2, 2019
1 parent 7cab472 commit 71a7530
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 1 deletion.
74 changes: 74 additions & 0 deletions compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
Expand Up @@ -9116,6 +9116,77 @@ INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {
#define INIT_ARC4RANDOM
#endif

#if SANITIZER_INTERCEPT_POPEN
INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);
if (command)
COMMON_INTERCEPTOR_READ_RANGE(ctx, command, REAL(strlen)(command) + 1);
if (type)
COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
__sanitizer_FILE *res = REAL(popen)(command, type);
COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
if (res) unpoison_file(res);
return res;
}
#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)
#else
#define INIT_POPEN
#endif

#if SANITIZER_INTERCEPT_POPENVE
INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,
char *const *argv, char *const *envp, const char *type) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);
if (path)
COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
if (argv) {
for (char *const *pa = argv; ; ++pa) {
COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
if (!*pa)
break;
COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
}
}
if (envp) {
for (char *const *pa = envp; ; ++pa) {
COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
if (!*pa)
break;
COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
}
}
if (type)
COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
__sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);
COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
if (res) unpoison_file(res);
return res;
}
#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)
#else
#define INIT_POPENVE
#endif

#if SANITIZER_INTERCEPT_PCLOSE
INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);
COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
const FileMetadata *m = GetInterceptorMetadata(fp);
int res = REAL(pclose)(fp);
if (m) {
COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
DeleteInterceptorMetadata(fp);
}
return res;
}
#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);
#else
#define INIT_PCLOSE
#endif

static void InitializeCommonInterceptors() {
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
interceptor_metadata_map =
Expand Down Expand Up @@ -9398,6 +9469,9 @@ static void InitializeCommonInterceptors() {
INIT_CDB;
INIT_GETFSENT;
INIT_ARC4RANDOM;
INIT_POPEN;
INIT_POPENVE;
INIT_PCLOSE;

INIT___PRINTF_CHK;
}
Expand Up @@ -548,4 +548,8 @@
#define SANITIZER_INTERCEPT_GETFSENT (SI_FREEBSD || SI_NETBSD || SI_MAC)
#define SANITIZER_INTERCEPT_ARC4RANDOM (SI_FREEBSD || SI_NETBSD)

#define SANITIZER_INTERCEPT_POPEN SI_POSIX
#define SANITIZER_INTERCEPT_POPENVE SI_NETBSD
#define SANITIZER_INTERCEPT_PCLOSE SI_POSIX

#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
3 changes: 2 additions & 1 deletion compiler-rt/lib/tsan/rtl/tsan_interceptors.cc
Expand Up @@ -2254,7 +2254,8 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc,
(void) ctx;

#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) \
Acquire(thr, pc, File2addr(path)); \
if (path) \
Acquire(thr, pc, File2addr(path)); \
if (file) { \
int fd = fileno_unlocked(file); \
if (fd >= 0) FdFileCreate(thr, pc, fd); \
Expand Down

0 comments on commit 71a7530

Please sign in to comment.