diff --git a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp @@ -98,12 +98,13 @@ if (VforkWhitelist.empty()) { // According to manpage. const char *ids[] = { - "_exit", "_Exit", + "_exit", "execl", - "execlp", "execle", + "execlp", "execv", + "execve", "execvp", "execvpe", nullptr diff --git a/clang/test/Analysis/Inputs/system-header-simulator.h b/clang/test/Analysis/Inputs/system-header-simulator.h --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -98,6 +98,12 @@ pid_t fork(void); pid_t vfork(void); int execl(const char *path, const char *arg, ...); +int execle(const char *path, const char *arg, ...); +int execlp(const char *file, const char *arg, ...); +int execv(const char *path, char *const argv[]); +int execve(const char *path, char *const argv[], char *const envp[]); +int execvp(const char *file, char *const argv[]); +int execvpe(const char *file, char *const argv[], char *const envp[]); void exit(int status) __attribute__ ((__noreturn__)); void _exit(int status) __attribute__ ((__noreturn__)); diff --git a/clang/test/Analysis/vfork.c b/clang/test/Analysis/vfork.c --- a/clang/test/Analysis/vfork.c +++ b/clang/test/Analysis/vfork.c @@ -6,7 +6,7 @@ void foo(); // Ensure that child process is properly checked. -int f1(int x) { +int f1(int x, int y) { pid_t pid = vfork(); // expected-warning{{Call to function 'vfork' is insecure}} if (pid != 0) return 0; @@ -16,7 +16,29 @@ // Ensure that modifying pid is ok. pid = 1; // no-warning // Ensure that calling whitelisted routines is ok. - execl("", "", 0); // no-warning + switch (y) { + case 0: + execl("", "", 0); // no-warning + break; + case 1: + execle("", "", 0); // no-warning + break; + case 2: + execlp("", "", 0); // no-warning + break; + case 3: + execv("", NULL); // no-warning + break; + case 4: + execve("", NULL, NULL); // no-warning + break; + case 5: + execvp("", NULL); // no-warning + break; + case 6: + execvpe("", NULL, NULL); // no-warning + break; + } _exit(1); // no-warning break; case 1: