137 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify %s2// RUN: %clang_analyze_cc1 -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify -x c++ %s3 4#include "Inputs/system-header-simulator.h"5 6void foo(void);7 8// Ensure that child process is properly checked.9int f1(int x, int y) {10 pid_t pid = vfork(); // expected-warning{{Call to function 'vfork' is insecure}}11 if (pid != 0)12 return 0;13 14 switch (x) {15 case 0:16 // Ensure that modifying pid is ok.17 pid = 1; // no-warning18 // Ensure that calling allowlisted routines is ok.19 switch (y) {20 case 0:21 execl("", "", 0); // no-warning22 break;23 case 1:24 execle("", "", 0); // no-warning25 break;26 case 2:27 execlp("", "", 0); // no-warning28 break;29 case 3:30 execv("", NULL); // no-warning31 break;32 case 4:33 execve("", NULL, NULL); // no-warning34 break;35 case 5:36 execvp("", NULL); // no-warning37 break;38 case 6:39 execvpe("", NULL, NULL); // no-warning40 break;41 }42 _exit(1); // no-warning43 break;44 case 1:45 // Ensure that writing variables is prohibited.46 x = 0; // expected-warning{{This assignment is prohibited after a successful vfork}}47 break;48 case 2:49 // Ensure that calling functions is prohibited.50 foo(); // expected-warning{{This function call is prohibited after a successful vfork}}51 break;52 default:53 // Ensure that returning from function is prohibited.54 return 0; // expected-warning{{Return is prohibited after a successful vfork; call _exit() instead}}55 }56 57 while(1);58}59 60// Same as previous but without explicit pid variable.61int f2(int x) {62 pid_t pid = vfork(); // expected-warning{{Call to function 'vfork' is insecure}}63 64 switch (x) {65 case 0:66 // Ensure that writing pid is ok.67 pid = 1; // no-warning68 // Ensure that calling allowlisted routines is ok.69 execl("", "", 0); // no-warning70 _exit(1); // no-warning71 break;72 case 1:73 // Ensure that writing variables is prohibited.74 x = 0; // expected-warning{{This assignment is prohibited after a successful vfork}}75 break;76 case 2:77 // Ensure that calling functions is prohibited.78 foo(); // expected-warning{{This function call is prohibited after a successful vfork}}79 break;80 default:81 // Ensure that returning from function is prohibited.82 return 0; // expected-warning{{Return is prohibited after a successful vfork; call _exit() instead}}83 }84 85 while(1);86}87 88// Ensure that parent process isn't restricted.89int f3(int x) {90 if (vfork() == 0) // expected-warning{{Call to function 'vfork' is insecure}}91 _exit(1);92 x = 0; // no-warning93 foo(); // no-warning94 return 0;95} // no-warning96 97// Unbound pids are special so test them separately.98void f4(int x) {99 switch (x) {100 case 0:101 vfork(); // expected-warning{{Call to function 'vfork' is insecure}}102 x = 0; // expected-warning{{This assignment is prohibited after a successful vfork}}103 break;104 105 case 1:106 {107 char args[2];108 switch (vfork()) { // expected-warning{{Call to function 'vfork' is insecure}}109 case 0:110 args[0] = 0; // expected-warning{{This assignment is prohibited after a successful vfork}}111 exit(1);112 }113 break;114 }115 116 case 2:117 {118 pid_t pid;119 if ((pid = vfork()) == 0) // expected-warning{{Call to function 'vfork' is insecure}}120 while(1); // no-warning121 break;122 }123 }124 while(1);125} //no-warning126 127 128void f5(void) {129 // See "libxtables: move some code to avoid cautions in vfork man page"130 // (http://lists.netfilter.org/pipermail/netfilter-buglog/2014-October/003280.html).131 if (vfork() == 0) { // expected-warning{{Call to function 'vfork' is insecure}}132 execl("prog", "arg1", 0); // no-warning133 exit(1); // expected-warning{{This function call is prohibited after a successful vfork}}134 }135}136 137