[RISCV][FMV] Support target_clones (#85786)
[llvm-project.git] / clang / test / Analysis / security-syntax-checks.m
blob154f0c1bae427c0259a5b9ba9c87efd7baee4ffb
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 \
11 // RUN:   -DVARIANT \
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 #ifdef USE_BUILTINS
21 # define BUILTIN(f) __builtin_ ## f
22 #else /* USE_BUILTINS */
23 # define BUILTIN(f) f
24 #endif /* USE_BUILTINS */
26 #include "Inputs/system-header-simulator-for-valist.h"
27 #include "Inputs/system-header-simulator-for-simple-stream.h"
29 typedef typeof(sizeof(int)) size_t;
32 // rule request: floating point used as loop condition (FLP30-C, FLP-30-CPP)
34 // For reference: https://www.securecoding.cert.org/confluence/display/seccode/FLP30-C.+Do+not+use+floating+point+variables+as+loop+counters
36 void test_float_condition(void) {
37   for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
38   for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
39   for (float x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
40   for (double x = 100000001.0; x <= 100000010.0; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
41   for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
42   
43   for (double x = 100000001.0; 100000010.0 >= x; x = x + 1.0 ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
44   
45   int i = 0;
46   for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++, ++i ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
47   
48   typedef float FooType;
49   for (FooType x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'FooType'}}
52 // Obsolete function bcmp
53 int bcmp(const void *, const void *, size_t);
55 int test_bcmp(void *a, void *b, size_t n) {
56   return bcmp(a, b, n); // expected-warning{{The bcmp() function is obsoleted by memcmp()}}
59 // Obsolete function bcopy
60 void bcopy(const void *, void *, size_t);
62 void test_bcopy(const void *a, void *b, size_t n) {
63   bcopy(a, b, n); // expected-warning{{The bcopy() function is obsoleted by memcpy() or memmove(}}
66 // Obsolete function bzero
67 void bzero(void *, size_t);
69 void test_bzero(void *a, size_t n) {
70   bzero(a, n); // expected-warning{{The bzero() function is obsoleted by memset()}}
73 // rule request: gets() buffer overflow
74 // Part of recommendation: 300-BSI (buildsecurityin.us-cert.gov)
75 char* gets(char *buf);
77 void test_gets(void) {
78   char buff[1024];
79   gets(buff); // expected-warning{{Call to function 'gets' is extremely insecure as it can always result in a buffer overflow}}
82 int getpw(unsigned int uid, char *buf);
84 void test_getpw(void) {
85   char buff[1024];
86   getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid()}}
89 // CWE-273: Failure to Check Whether Privileges Were Dropped Successfully
90 typedef unsigned int __uint32_t;
91 typedef __uint32_t __darwin_uid_t;
92 typedef __uint32_t __darwin_gid_t;
93 typedef __darwin_uid_t uid_t;
94 typedef __darwin_gid_t gid_t;
95 int setuid(uid_t);
96 int setregid(gid_t, gid_t);
97 int setreuid(uid_t, uid_t);
98 extern void check(int);
99 void abort(void);
101 void test_setuid(void) 
103   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}}
104   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}}
105   if (setuid (2) != 0)
106     abort();
108   // Currently the 'setuid' check is not flow-sensitive, and only looks
109   // at whether the function was called in a compound statement.  This
110   // will lead to false negatives, but there should be no false positives.
111   int t = setuid(2);  // no-warning
112   (void)setuid (2); // no-warning
114   check(setuid (2)); // no-warning
116   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}}
117   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}}
120 // CWE-338: Use of cryptographically weak prng
121 typedef  unsigned short *ushort_ptr_t;  // Test that sugar doesn't confuse the warning.
122 int      rand(void);
123 double   drand48(void);
124 double   erand48(unsigned short[3]);
125 long     jrand48(ushort_ptr_t);
126 void     lcong48(unsigned short[7]);
127 long     lrand48(void);
128 long     mrand48(void);
129 long     nrand48(unsigned short[3]);
130 long     random(void);
131 int      rand_r(unsigned *);
133 void test_rand(void)
135   unsigned short a[7];
136   unsigned b;
137   
138   rand();       // expected-warning{{Function 'rand' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
139   drand48();    // expected-warning{{Function 'drand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
140   erand48(a);   // expected-warning{{Function 'erand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
141   jrand48(a);   // expected-warning{{Function 'jrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
142   lcong48(a);   // expected-warning{{Function 'lcong48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
143   lrand48();    // expected-warning{{Function 'lrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
144   mrand48();    // expected-warning{{Function 'mrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
145   nrand48(a);   // expected-warning{{Function 'nrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
146   rand_r(&b);   // expected-warning{{Function 'rand_r' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
147   random();     // expected-warning{{The 'random' function produces a sequence of values that an adversary may be able to predict.  Use 'arc4random' instead}}
150 char *mktemp(char *buf);
152 void test_mktemp(void) {
153   char *x = mktemp("/tmp/zxcv"); // expected-warning{{Call to function 'mktemp' is insecure as it always creates or uses insecure temporary file}}
157 //===----------------------------------------------------------------------===
158 // strcpy()
159 //===----------------------------------------------------------------------===
160 #ifdef VARIANT
162 #define __strcpy_chk BUILTIN(__strcpy_chk)
163 char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
165 #define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1)
167 #else /* VARIANT */
169 #define strcpy BUILTIN(strcpy)
170 char *strcpy(char *restrict s1, const char *restrict s2);
172 #endif /* VARIANT */
174 void test_strcpy(void) {
175   char x[4];
176   char *y;
178   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}}
181 void test_strcpy_2(void) {
182   char x[4];
183   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}}
186 void test_strcpy_safe(void) {
187   char x[5];
188   strcpy(x, "abcd");
191 void test_strcpy_safe_2(void) {
192   struct {char s1[100];} s;
193   strcpy(s.s1, "hello");
196 //===----------------------------------------------------------------------===
197 // strcat()
198 //===----------------------------------------------------------------------===
199 #ifdef VARIANT
201 #define __strcat_chk BUILTIN(__strcat_chk)
202 char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
204 #define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
206 #else /* VARIANT */
208 #define strcat BUILTIN(strcat)
209 char *strcat(char *restrict s1, const char *restrict s2);
211 #endif /* VARIANT */
213 void test_strcat(void) {
214   char x[4];
215   char *y;
217   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}}
220 //===----------------------------------------------------------------------===
221 // vfork()
222 //===----------------------------------------------------------------------===
223 typedef int __int32_t;
224 typedef __int32_t pid_t;
225 pid_t vfork(void);
227 void test_vfork(void) {
228   vfork(); //expected-warning{{Call to function 'vfork' is insecure as it can lead to denial of service situations in the parent process}}
231 //===----------------------------------------------------------------------===
232 // mkstemp()
233 //===----------------------------------------------------------------------===
235 char *mkdtemp(char *template);
236 int mkstemps(char *template, int suffixlen);
237 int mkstemp(char *template);
238 char *mktemp(char *template);
240 void test_mkstemp(void) {
241   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)}}
242   mkstemp("XXXXXX");
243   mkstemp("XXXXXXX");
244   mkstemps("XXXXXX", 0);
245   mkstemps("XXXXXX", 1); // expected-warning {{5 'X's seen}}
246   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)}}
247   mkdtemp("XX"); // expected-warning {{2 'X's seen}}
248   mkstemp("X"); // expected-warning {{Call to 'mkstemp' should have at least 6 'X's in the format string to be secure (1 'X' seen)}}
249   mkdtemp("XXXXXX");
253 //===----------------------------------------------------------------------===
254 // deprecated or unsafe buffer handling
255 //===----------------------------------------------------------------------===
256 typedef int wchar_t;
258 int sprintf(char *str, const char *format, ...);
259 //int vsprintf (char *s, const char *format, va_list arg);
260 int scanf(const char *format, ...);
261 int wscanf(const wchar_t *format, ...);
262 int fscanf(FILE *stream, const char *format, ...);
263 int fwscanf(FILE *stream, const wchar_t *format, ...);
264 int vscanf(const char *format, va_list arg);
265 int vwscanf(const wchar_t *format, va_list arg);
266 int vfscanf(FILE *stream, const char *format, va_list arg);
267 int vfwscanf(FILE *stream, const wchar_t *format, va_list arg);
268 int sscanf(const char *s, const char *format, ...);
269 int swscanf(const wchar_t *ws, const wchar_t *format, ...);
270 int vsscanf(const char *s, const char *format, va_list arg);
271 int vswscanf(const wchar_t *ws, const wchar_t *format, va_list arg);
272 int swprintf(wchar_t *ws, size_t len, const wchar_t *format, ...);
273 int snprintf(char *s, size_t n, const char *format, ...);
274 int vswprintf(wchar_t *ws, size_t len, const wchar_t *format, va_list arg);
275 int vsnprintf(char *s, size_t n, const char *format, va_list arg);
276 void *memcpy(void *destination, const void *source, size_t num);
277 void *memmove(void *destination, const void *source, size_t num);
278 char *strncpy(char *destination, const char *source, size_t num);
279 char *strncat(char *destination, const char *source, size_t num);
280 void *memset(void *ptr, int value, size_t num);
282 void test_deprecated_or_unsafe_buffer_handling_1(void) {
283   char buf [5];
284   wchar_t wbuf [5];
285   int a;
286   FILE *file;
287   sprintf(buf, "a"); // expected-warning{{Call to function 'sprintf' is insecure}}
288   scanf("%d", &a); // expected-warning{{Call to function 'scanf' is insecure}}
289   scanf("%s", buf); // expected-warning{{Call to function 'scanf' is insecure}}
290   scanf("%4s", buf); // expected-warning{{Call to function 'scanf' is insecure}}
291   wscanf((const wchar_t*) L"%s", buf); // expected-warning{{Call to function 'wscanf' is insecure}}
292   fscanf(file, "%d", &a); // expected-warning{{Call to function 'fscanf' is insecure}}
293   fscanf(file, "%s", buf); // expected-warning{{Call to function 'fscanf' is insecure}}
294   fscanf(file, "%4s", buf); // expected-warning{{Call to function 'fscanf' is insecure}}
295   fwscanf(file, (const wchar_t*) L"%s", wbuf); // expected-warning{{Call to function 'fwscanf' is insecure}}
296   sscanf("5", "%d", &a); // expected-warning{{Call to function 'sscanf' is insecure}}
297   sscanf("5", "%s", buf); // expected-warning{{Call to function 'sscanf' is insecure}}
298   sscanf("5", "%4s", buf); // expected-warning{{Call to function 'sscanf' is insecure}}
299   swscanf(L"5", (const wchar_t*) L"%s", wbuf); // expected-warning{{Call to function 'swscanf' is insecure}}
300   swprintf(L"5", 1, (const wchar_t*) L"%s", wbuf); // expected-warning{{Call to function 'swprintf' is insecure}}
301   snprintf("5", 1, "%s", buf); // expected-warning{{Call to function 'snprintf' is insecure}}
302   memcpy(buf, wbuf, 1); // expected-warning{{Call to function 'memcpy' is insecure}}
303   memmove(buf, wbuf, 1); // expected-warning{{Call to function 'memmove' is insecure}}
304   strncpy(buf, "a", 1); // expected-warning{{Call to function 'strncpy' is insecure}}
305   strncat(buf, "a", 1); // expected-warning{{Call to function 'strncat' is insecure}}
306   memset(buf, 'a', 1); // expected-warning{{Call to function 'memset' is insecure}}
309 void test_deprecated_or_unsafe_buffer_handling_2(const char *format, ...) {
310   char buf [5];
311   FILE *file;
312   va_list args;
313   va_start(args, format);
314   vsprintf(buf, format, args); // expected-warning{{Call to function 'vsprintf' is insecure}}
315   vscanf(format, args); // expected-warning{{Call to function 'vscanf' is insecure}}
316   vfscanf(file, format, args); // expected-warning{{Call to function 'vfscanf' is insecure}}
317   vsscanf("a", format, args); // expected-warning{{Call to function 'vsscanf' is insecure}}
318   vsnprintf("a", 1, format, args); // expected-warning{{Call to function 'vsnprintf' is insecure}}
321 void test_deprecated_or_unsafe_buffer_handling_3(const wchar_t *format, ...) {
322   wchar_t wbuf [5];
323   FILE *file;
324   va_list args;
325   va_start(args, format);
326   vwscanf(format, args); // expected-warning{{Call to function 'vwscanf' is insecure}}
327   vfwscanf(file, format, args); // expected-warning{{Call to function 'vfwscanf' is insecure}}
328   vswscanf(L"a", format, args); // expected-warning{{Call to function 'vswscanf' is insecure}}
329   vswprintf(L"a", 1, format, args); // expected-warning{{Call to function 'vswprintf' is insecure}}