From 5a11233a2fa58a734dbed23e2232f55cdf4b3321 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Tue, 18 Feb 2020 08:40:02 +0300 Subject: [PATCH] [analyzer] VforkChecker: allow execve after vfork. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit In the path-sensitive vfork() checker that keeps a list of operations allowed after a successful vfork(), unforget to include execve() in the list. Patch by Jan Včelák! Differential Revision: https://reviews.llvm.org/D73629 --- clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp | 5 +++-- .../test/Analysis/Inputs/system-header-simulator.h | 6 +++++ clang/test/Analysis/vfork.c | 26 ++++++++++++++++++++-- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp index 6724eea..077a348 100644 --- a/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/VforkChecker.cpp @@ -98,12 +98,13 @@ bool VforkChecker::isCallWhitelisted(const IdentifierInfo *II, 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 index 8542387..afbaedd 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator.h +++ b/clang/test/Analysis/Inputs/system-header-simulator.h @@ -98,6 +98,12 @@ typedef int pid_t; 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 index da1b5da..8552b5f 100644 --- 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 @@ int f1(int x) { // 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: -- 2.7.4