1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,security.SetgidSetuidOrder -verify %s
10 int setreuid(uid_t
, uid_t
);
11 int setregid(gid_t
, gid_t
);
12 int setresuid(uid_t
, uid_t
, uid_t
);
13 int setresgid(gid_t
, gid_t
, gid_t
);
20 void correct_order() {
21 // A correct revocation sequence starts here.
22 if (setgid(getgid()) == -1)
24 if (setuid(getuid()) == -1)
26 // No warning for the following setgid statement.
27 // The previous setgid and setuid calls are a correct privilege revocation
28 // sequence. The checker does not care about the following statements (except
29 // if a wrong setuid-setgid sequence follows again).
30 if (setgid(getgid()) == -1)
34 void incorrect_after_correct() {
35 if (setgid(getgid()) == -1)
37 if (setuid(getuid()) == -1)
39 // Incorrect sequence starts here.
40 if (setuid(getuid()) == -1)
42 if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
46 void incorrect_order() {
47 if (setuid(getuid()) == -1)
49 if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
51 if (setgid(getgid()) == -1)
55 void warn_at_second_time() {
56 if (setuid(getuid()) == -1)
58 if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
60 if (setuid(getuid()) == -1)
62 if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
70 if (setuid(f_uid()) == -1)
72 if (setgid(getgid()) == -1)
77 if (setuid(getuid()) == -1)
79 if (setgid(f_gid()) == -1)
81 if (setgid(getgid()) == -1)
85 void setuid_other_between() {
86 if (setuid(getuid()) == -1)
88 if (setuid(f_uid()) == -1)
90 if (setgid(getgid()) == -1)
94 void setgid_with_getuid() {
95 if (setuid(getuid()) == -1)
97 // add a clang-tidy check for this case?
98 if (setgid(getuid()) == -1)
102 void setuid_with_getgid() {
103 // add a clang-tidy check for this case?
104 if (setuid(getgid()) == -1)
106 if (setgid(getgid()) == -1)
111 return setuid(getuid());
115 return setgid(getgid()); // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
118 void function_calls() {
119 if (f_setuid() == -1)
121 if (f_setgid() == -1)
125 void seteuid_between() {
126 if (setuid(getuid()) == -1)
128 if (seteuid(getuid()) == -1)
130 if (setgid(getgid()) == -1)
134 void setegid_between() {
135 if (setuid(getuid()) == -1)
137 if (setegid(getgid()) == -1)
139 if (setgid(getgid()) == -1)
143 void setreuid_between() {
144 if (setuid(getuid()) == -1)
146 if (setreuid(getuid(), getuid()) == -1)
148 if (setgid(getgid()) == -1)
152 void setregid_between() {
153 if (setuid(getuid()) == -1)
155 if (setregid(getgid(), getgid()) == -1)
157 if (setgid(getgid()) == -1)
161 void setresuid_between() {
162 if (setuid(getuid()) == -1)
164 if (setresuid(getuid(), getuid(), getuid()) == -1)
166 if (setgid(getgid()) == -1)
170 void setresgid_between() {
171 if (setuid(getuid()) == -1)
173 if (setresgid(getgid(), getgid(), getgid()) == -1)
175 if (setgid(getgid()) == -1)
179 void getgid_getuid_between() {
180 if (setuid(getuid()) == -1)
184 if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
188 void stored_getgid_getuid() {
189 // possible future improvement: detect this case
194 if (setgid(g
) == -1) // no warning
200 void other_unknown_function_between() {
201 if (setuid(getuid()) == -1)
204 if (setgid(getgid()) == -1) // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
208 void setuid_error_case() {
209 if (setuid(getuid()) == -1) {
210 // No warning if we know that the first setuid call has failed.
211 (void)setgid(getgid());
214 (void)setgid(getgid()); // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
217 void setuid_success_case() {
218 if (setuid(getuid()) == 0) {
219 if (setgid(getgid()) == 0) { // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
224 void incorrect_order_compare_zero() {
225 if (setuid(getuid()) != 0)
227 (void)setgid(getgid()); // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
230 void setuid_error_case_compare_zero() {
231 if (setuid(getuid()) != 0) {
232 // No warning if we know that the first setuid call has failed.
233 (void)setgid(getgid());
238 void incorrect_order_compare_other() {
239 if (setuid(getuid()) == -2) {
240 // This is a case for improvement:
241 // The checker does not recognize that this is an invalid error check,
242 // but this is really another type of bug not related to this checker.
243 (void)setgid(getgid()); // warning should appear here
246 if (setgid(getgid()) == -2) { // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}
253 void incorrect_order_compare_var() {
254 if (setuid(getuid()) == FAIL
)
256 (void)setgid(getgid()); // expected-warning{{A 'setgid(getgid())' call following a 'setuid(getuid())' call is likely to fail}}