forked from OSchip/llvm-project
[sanitizer_common] Implement popen, popenve, pclose interceptors
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
This commit is contained in:
parent
7cab4722d3
commit
71a75307ae
|
@ -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 =
|
||||
|
@ -9398,6 +9469,9 @@ static void InitializeCommonInterceptors() {
|
|||
INIT_CDB;
|
||||
INIT_GETFSENT;
|
||||
INIT_ARC4RANDOM;
|
||||
INIT_POPEN;
|
||||
INIT_POPENVE;
|
||||
INIT_PCLOSE;
|
||||
|
||||
INIT___PRINTF_CHK;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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); \
|
||||
|
|
Loading…
Reference in New Issue