diff options
Diffstat (limited to 'test/Analysis/vfork.c')
-rw-r--r-- | test/Analysis/vfork.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/test/Analysis/vfork.c b/test/Analysis/vfork.c new file mode 100644 index 0000000..c7a02fa --- /dev/null +++ b/test/Analysis/vfork.c @@ -0,0 +1,114 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify -x c++ %s + +#include "Inputs/system-header-simulator.h" + +void foo(); + +// Ensure that child process is properly checked. +int f1(int x) { + pid_t pid = vfork(); // expected-warning{{Call to function 'vfork' is insecure}} + if (pid != 0) + return 0; + + switch (x) { + case 0: + // Ensure that modifying pid is ok. + pid = 1; // no-warning + // Ensure that calling whitelisted routines is ok. + execl("", "", 0); // no-warning + _exit(1); // no-warning + break; + case 1: + // Ensure that writing variables is prohibited. + x = 0; // expected-warning{{This assignment is prohibited after a successful vfork}} + break; + case 2: + // Ensure that calling functions is prohibited. + foo(); // expected-warning{{This function call is prohibited after a successful vfork}} + break; + default: + // Ensure that returning from function is prohibited. + return 0; // expected-warning{{Return is prohibited after a successful vfork; call _exit() instead}} + } + + while(1); +} + +// Same as previous but without explicit pid variable. +int f2(int x) { + pid_t pid = vfork(); // expected-warning{{Call to function 'vfork' is insecure}} + + switch (x) { + case 0: + // Ensure that writing pid is ok. + pid = 1; // no-warning + // Ensure that calling whitelisted routines is ok. + execl("", "", 0); // no-warning + _exit(1); // no-warning + break; + case 1: + // Ensure that writing variables is prohibited. + x = 0; // expected-warning{{This assignment is prohibited after a successful vfork}} + break; + case 2: + // Ensure that calling functions is prohibited. + foo(); // expected-warning{{This function call is prohibited after a successful vfork}} + break; + default: + // Ensure that returning from function is prohibited. + return 0; // expected-warning{{Return is prohibited after a successful vfork; call _exit() instead}} + } + + while(1); +} + +// Ensure that parent process isn't restricted. +int f3(int x) { + if (vfork() == 0) // expected-warning{{Call to function 'vfork' is insecure}} + _exit(1); + x = 0; // no-warning + foo(); // no-warning + return 0; +} // no-warning + +// Unbound pids are special so test them separately. +void f4(int x) { + switch (x) { + case 0: + vfork(); // expected-warning{{Call to function 'vfork' is insecure}} + x = 0; // expected-warning{{This assignment is prohibited after a successful vfork}} + break; + + case 1: + { + char args[2]; + switch (vfork()) { // expected-warning{{Call to function 'vfork' is insecure}} + case 0: + args[0] = 0; // expected-warning{{This assignment is prohibited after a successful vfork}} + exit(1); + } + break; + } + + case 2: + { + pid_t pid; + if ((pid = vfork()) == 0) // expected-warning{{Call to function 'vfork' is insecure}} + while(1); // no-warning + break; + } + } + while(1); +} //no-warning + + +void f5() { + // See "libxtables: move some code to avoid cautions in vfork man page" + // (http://lists.netfilter.org/pipermail/netfilter-buglog/2014-October/003280.html). + if (vfork() == 0) { // expected-warning{{Call to function 'vfork' is insecure}} + execl("prog", "arg1", 0); // no-warning + exit(1); // expected-warning{{This function call is prohibited after a successful vfork}} + } +} + |