1 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 %s -verify -Wno-fortify-source \
2 // RUN: -analyzer-checker=security.insecureAPI \
3 // RUN: -analyzer-checker=security.FloatLoopCounter
5 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 %s -verify -Wno-fortify-source \
6 // RUN: -DUSE_BUILTINS \
7 // RUN: -analyzer-checker=security.insecureAPI \
8 // RUN: -analyzer-checker=security.FloatLoopCounter
10 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 %s -verify -Wno-fortify-source \
12 // RUN: -analyzer-checker=security.insecureAPI \
13 // RUN: -analyzer-checker=security.FloatLoopCounter
15 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 %s -verify -Wno-fortify-source \
16 // RUN: -DUSE_BUILTINS -DVARIANT \
17 // RUN: -analyzer-checker=security.insecureAPI \
18 // RUN: -analyzer-checker=security.FloatLoopCounter
20 // RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi %s -verify -Wno-fortify-source \
21 // RUN: -analyzer-checker=security.insecureAPI \
22 // RUN: -analyzer-checker=security.FloatLoopCounter
24 // RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi %s -verify -Wno-fortify-source \
25 // RUN: -DUSE_BUILTINS \
26 // RUN: -analyzer-checker=security.insecureAPI \
27 // RUN: -analyzer-checker=security.FloatLoopCounter
29 // RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi %s -verify -Wno-fortify-source \
31 // RUN: -analyzer-checker=security.insecureAPI \
32 // RUN: -analyzer-checker=security.FloatLoopCounter
34 // RUN: %clang_analyze_cc1 -triple x86_64-unknown-cloudabi %s -verify -Wno-fortify-source \
35 // RUN: -DUSE_BUILTINS -DVARIANT \
36 // RUN: -analyzer-checker=security.insecureAPI \
37 // RUN: -analyzer-checker=security.FloatLoopCounter
40 # define BUILTIN(f) __builtin_ ## f
41 #else /* USE_BUILTINS */
43 #endif /* USE_BUILTINS */
45 #include "Inputs/system-header-simulator-for-valist.h"
46 #include "Inputs/system-header-simulator-for-simple-stream.h"
48 typedef typeof(sizeof(int)) size_t;
51 // <rdar://problem/6336718> rule request: floating point used as loop
52 // condition (FLP30-C, FLP-30-CPP)
54 // For reference: https://www.securecoding.cert.org/confluence/display/seccode/FLP30-C.+Do+not+use+floating+point+variables+as+loop+counters
56 void test_float_condition(void) {
57 for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
58 for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
59 for (float x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
60 for (double x = 100000001.0; x <= 100000010.0; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
61 for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
63 for (double x = 100000001.0; 100000010.0 >= x; x = x + 1.0 ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
66 for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++, ++i ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
68 typedef float FooType;
69 for (FooType x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'FooType'}}
72 // Obsolete function bcmp
73 int bcmp(const void *, const void *, size_t);
75 int test_bcmp(void *a, void *b, size_t n) {
76 return bcmp(a, b, n); // expected-warning{{The bcmp() function is obsoleted by memcmp()}}
79 // Obsolete function bcopy
80 void bcopy(void *, void *, size_t);
82 void test_bcopy(void *a, void *b, size_t n) {
83 bcopy(a, b, n); // expected-warning{{The bcopy() function is obsoleted by memcpy() or memmove(}}
86 // Obsolete function bzero
87 void bzero(void *, size_t);
89 void test_bzero(void *a, size_t n) {
90 bzero(a, n); // expected-warning{{The bzero() function is obsoleted by memset()}}
93 // <rdar://problem/6335715> rule request: gets() buffer overflow
94 // Part of recommendation: 300-BSI (buildsecurityin.us-cert.gov)
95 char* gets(char *buf);
97 void test_gets(void) {
99 gets(buff); // expected-warning{{Call to function 'gets' is extremely insecure as it can always result in a buffer overflow}}
102 int getpw(unsigned int uid, char *buf);
104 void test_getpw(void) {
106 getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid()}}
109 // <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were
110 // Dropped Successfully
111 typedef unsigned int __uint32_t;
112 typedef __uint32_t __darwin_uid_t;
113 typedef __uint32_t __darwin_gid_t;
114 typedef __darwin_uid_t uid_t;
115 typedef __darwin_gid_t gid_t;
117 int setregid(gid_t, gid_t);
118 int setreuid(uid_t, uid_t);
119 extern void check(int);
122 void test_setuid(void)
124 setuid(2); // expected-warning{{The return value from the call to 'setuid' is not checked. If an error occurs in 'setuid', the following code may execute with unexpected privileges}}
125 setuid(0); // expected-warning{{The return value from the call to 'setuid' is not checked. If an error occurs in 'setuid', the following code may execute with unexpected privileges}}
129 // Currently the 'setuid' check is not flow-sensitive, and only looks
130 // at whether the function was called in a compound statement. This
131 // will lead to false negatives, but there should be no false positives.
132 int t = setuid(2); // no-warning
133 (void)setuid (2); // no-warning
135 check(setuid (2)); // no-warning
137 setreuid(2,2); // expected-warning{{The return value from the call to 'setreuid' is not checked. If an error occurs in 'setreuid', the following code may execute with unexpected privileges}}
138 setregid(2,2); // expected-warning{{The return value from the call to 'setregid' is not checked. If an error occurs in 'setregid', the following code may execute with unexpected privileges}}
141 // <rdar://problem/6337100> CWE-338: Use of cryptographically weak prng
142 typedef unsigned short *ushort_ptr_t; // Test that sugar doesn't confuse the warning.
144 double drand48(void);
145 double erand48(unsigned short[3]);
146 long jrand48(ushort_ptr_t);
147 void lcong48(unsigned short[7]);
150 long nrand48(unsigned short[3]);
152 int rand_r(unsigned *);
159 rand(); // expected-warning{{Function 'rand' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
160 drand48(); // expected-warning{{Function 'drand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
161 erand48(a); // expected-warning{{Function 'erand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
162 jrand48(a); // expected-warning{{Function 'jrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
163 lcong48(a); // expected-warning{{Function 'lcong48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
164 lrand48(); // expected-warning{{Function 'lrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
165 mrand48(); // expected-warning{{Function 'mrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
166 nrand48(a); // expected-warning{{Function 'nrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
167 rand_r(&b); // expected-warning{{Function 'rand_r' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
168 random(); // expected-warning{{The 'random' function produces a sequence of values that an adversary may be able to predict. Use 'arc4random' instead}}
171 char *mktemp(char *buf);
173 void test_mktemp(void) {
174 char *x = mktemp("/tmp/zxcv"); // expected-warning{{Call to function 'mktemp' is insecure as it always creates or uses insecure temporary file}}
178 //===----------------------------------------------------------------------===
180 //===----------------------------------------------------------------------===
183 #define __strcpy_chk BUILTIN(__strcpy_chk)
184 char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
186 #define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1)
190 #define strcpy BUILTIN(strcpy)
191 char *strcpy(char *restrict s1, const char *restrict s2);
195 void test_strcpy(void) {
199 strcpy(x, y); //expected-warning{{Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119}}
202 void test_strcpy_2(void) {
204 strcpy(x, "abcd"); //expected-warning{{Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119}}
207 void test_strcpy_safe(void) {
212 void test_strcpy_safe_2(void) {
213 struct {char s1[100];} s;
214 strcpy(s.s1, "hello");
217 //===----------------------------------------------------------------------===
219 //===----------------------------------------------------------------------===
222 #define __strcat_chk BUILTIN(__strcat_chk)
223 char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
225 #define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
229 #define strcat BUILTIN(strcat)
230 char *strcat(char *restrict s1, const char *restrict s2);
234 void test_strcat(void) {
238 strcat(x, y); //expected-warning{{Call to function 'strcat' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcat'. CWE-119}}
241 //===----------------------------------------------------------------------===
243 //===----------------------------------------------------------------------===
244 typedef int __int32_t;
245 typedef __int32_t pid_t;
248 void test_vfork(void) {
249 vfork(); //expected-warning{{Call to function 'vfork' is insecure as it can lead to denial of service situations in the parent process}}
252 //===----------------------------------------------------------------------===
254 //===----------------------------------------------------------------------===
256 char *mkdtemp(char *template);
257 int mkstemps(char *template, int suffixlen);
258 int mkstemp(char *template);
259 char *mktemp(char *template);
261 void test_mkstemp(void) {
262 mkstemp("XX"); // expected-warning {{Call to 'mkstemp' should have at least 6 'X's in the format string to be secure (2 'X's seen)}}
265 mkstemps("XXXXXX", 0);
266 mkstemps("XXXXXX", 1); // expected-warning {{5 'X's seen}}
267 mkstemps("XXXXXX", 2); // expected-warning {{Call to 'mkstemps' should have at least 6 'X's in the format string to be secure (4 'X's seen, 2 characters used as a suffix)}}
268 mkdtemp("XX"); // expected-warning {{2 'X's seen}}
269 mkstemp("X"); // expected-warning {{Call to 'mkstemp' should have at least 6 'X's in the format string to be secure (1 'X' seen)}}
274 //===----------------------------------------------------------------------===
275 // deprecated or unsafe buffer handling
276 //===----------------------------------------------------------------------===
279 int sprintf(char *str, const char *format, ...);
280 //int vsprintf (char *s, const char *format, va_list arg);
281 int scanf(const char *format, ...);
282 int wscanf(const wchar_t *format, ...);
283 int fscanf(FILE *stream, const char *format, ...);
284 int fwscanf(FILE *stream, const wchar_t *format, ...);
285 int vscanf(const char *format, va_list arg);
286 int vwscanf(const wchar_t *format, va_list arg);
287 int vfscanf(FILE *stream, const char *format, va_list arg);
288 int vfwscanf(FILE *stream, const wchar_t *format, va_list arg);
289 int sscanf(const char *s, const char *format, ...);
290 int swscanf(const wchar_t *ws, const wchar_t *format, ...);
291 int vsscanf(const char *s, const char *format, va_list arg);
292 int vswscanf(const wchar_t *ws, const wchar_t *format, va_list arg);
293 int swprintf(wchar_t *ws, size_t len, const wchar_t *format, ...);
294 int snprintf(char *s, size_t n, const char *format, ...);
295 int vswprintf(wchar_t *ws, size_t len, const wchar_t *format, va_list arg);
296 int vsnprintf(char *s, size_t n, const char *format, va_list arg);
297 void *memcpy(void *destination, const void *source, size_t num);
298 void *memmove(void *destination, const void *source, size_t num);
299 char *strncpy(char *destination, const char *source, size_t num);
300 char *strncat(char *destination, const char *source, size_t num);
301 void *memset(void *ptr, int value, size_t num);
303 void test_deprecated_or_unsafe_buffer_handling_1(void) {
308 sprintf(buf, "a"); // expected-warning{{Call to function 'sprintf' is insecure}}
309 scanf("%d", &a); // expected-warning{{Call to function 'scanf' is insecure}}
310 scanf("%s", buf); // expected-warning{{Call to function 'scanf' is insecure}}
311 scanf("%4s", buf); // expected-warning{{Call to function 'scanf' is insecure}}
312 wscanf((const wchar_t*) L"%s", buf); // expected-warning{{Call to function 'wscanf' is insecure}}
313 fscanf(file, "%d", &a); // expected-warning{{Call to function 'fscanf' is insecure}}
314 fscanf(file, "%s", buf); // expected-warning{{Call to function 'fscanf' is insecure}}
315 fscanf(file, "%4s", buf); // expected-warning{{Call to function 'fscanf' is insecure}}
316 fwscanf(file, (const wchar_t*) L"%s", wbuf); // expected-warning{{Call to function 'fwscanf' is insecure}}
317 sscanf("5", "%d", &a); // expected-warning{{Call to function 'sscanf' is insecure}}
318 sscanf("5", "%s", buf); // expected-warning{{Call to function 'sscanf' is insecure}}
319 sscanf("5", "%4s", buf); // expected-warning{{Call to function 'sscanf' is insecure}}
320 swscanf(L"5", (const wchar_t*) L"%s", wbuf); // expected-warning{{Call to function 'swscanf' is insecure}}
321 swprintf(L"5", 1, (const wchar_t*) L"%s", wbuf); // expected-warning{{Call to function 'swprintf' is insecure}}
322 snprintf("5", 1, "%s", buf); // expected-warning{{Call to function 'snprintf' is insecure}}
323 memcpy(buf, wbuf, 1); // expected-warning{{Call to function 'memcpy' is insecure}}
324 memmove(buf, wbuf, 1); // expected-warning{{Call to function 'memmove' is insecure}}
325 strncpy(buf, "a", 1); // expected-warning{{Call to function 'strncpy' is insecure}}
326 strncat(buf, "a", 1); // expected-warning{{Call to function 'strncat' is insecure}}
327 memset(buf, 'a', 1); // expected-warning{{Call to function 'memset' is insecure}}
330 void test_deprecated_or_unsafe_buffer_handling_2(const char *format, ...) {
334 va_start(args, format);
335 vsprintf(buf, format, args); // expected-warning{{Call to function 'vsprintf' is insecure}}
336 vscanf(format, args); // expected-warning{{Call to function 'vscanf' is insecure}}
337 vfscanf(file, format, args); // expected-warning{{Call to function 'vfscanf' is insecure}}
338 vsscanf("a", format, args); // expected-warning{{Call to function 'vsscanf' is insecure}}
339 vsnprintf("a", 1, format, args); // expected-warning{{Call to function 'vsnprintf' is insecure}}
342 void test_deprecated_or_unsafe_buffer_handling_3(const wchar_t *format, ...) {
346 va_start(args, format);
347 vwscanf(format, args); // expected-warning{{Call to function 'vwscanf' is insecure}}
348 vfwscanf(file, format, args); // expected-warning{{Call to function 'vfwscanf' is insecure}}
349 vswscanf(L"a", format, args); // expected-warning{{Call to function 'vswscanf' is insecure}}
350 vswprintf(L"a", 1, format, args); // expected-warning{{Call to function 'vswprintf' is insecure}}