1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify %s
2 // RUN: %clang_analyze_cc1 -analyzer-checker=core,security.insecureAPI.vfork,unix.Vfork -verify -x c++ %s
3
4 #include "Inputs/system-header-simulator.h"
5
6 void foo();
7
8 // Ensure that child process is properly checked.
f1(int x,int y)9 int 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-warning
18 // Ensure that calling whitelisted routines is ok.
19 switch (y) {
20 case 0:
21 execl("", "", 0); // no-warning
22 break;
23 case 1:
24 execle("", "", 0); // no-warning
25 break;
26 case 2:
27 execlp("", "", 0); // no-warning
28 break;
29 case 3:
30 execv("", NULL); // no-warning
31 break;
32 case 4:
33 execve("", NULL, NULL); // no-warning
34 break;
35 case 5:
36 execvp("", NULL); // no-warning
37 break;
38 case 6:
39 execvpe("", NULL, NULL); // no-warning
40 break;
41 }
42 _exit(1); // no-warning
43 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.
f2(int x)61 int 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-warning
68 // Ensure that calling whitelisted routines is ok.
69 execl("", "", 0); // no-warning
70 _exit(1); // no-warning
71 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.
f3(int x)89 int f3(int x) {
90 if (vfork() == 0) // expected-warning{{Call to function 'vfork' is insecure}}
91 _exit(1);
92 x = 0; // no-warning
93 foo(); // no-warning
94 return 0;
95 } // no-warning
96
97 // Unbound pids are special so test them separately.
f4(int x)98 void 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-warning
121 break;
122 }
123 }
124 while(1);
125 } //no-warning
126
127
f5()128 void f5() {
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-warning
133 exit(1); // expected-warning{{This function call is prohibited after a successful vfork}}
134 }
135 }
136
137