blob: 9b7fb25edb1902b68827f1206a99bacd0044f945 [file] [log] [blame]
Ted Kremenekc54dc952012-01-20 01:44:29 +00001// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
2// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
3// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
4// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
Ed Schoutene5bdc852015-03-11 08:48:55 +00005// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
6// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
7// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
8// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
Lenny Maiorani6ffe7382011-03-31 22:09:14 +00009
10#ifdef USE_BUILTINS
11# define BUILTIN(f) __builtin_ ## f
12#else /* USE_BUILTINS */
13# define BUILTIN(f) f
14#endif /* USE_BUILTINS */
15
16typedef typeof(sizeof(int)) size_t;
17
Ted Kremenek9c497622009-07-23 21:34:35 +000018
19// <rdar://problem/6336718> rule request: floating point used as loop
20// condition (FLP30-C, FLP-30-CPP)
21//
22// For reference: https://www.securecoding.cert.org/confluence/display/seccode/FLP30-C.+Do+not+use+floating+point+variables+as+loop+counters
23//
24void test_float_condition() {
25 for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
26 for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
27 for (float x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
28 for (double x = 100000001.0; x <= 100000010.0; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
29 for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
30
31 for (double x = 100000001.0; 100000010.0 >= x; x = x + 1.0 ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
32
33 int i = 0;
34 for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++, ++i ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
35
36 typedef float FooType;
37 for (FooType x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'FooType'}}
38}
39
Ted Kremenek6610c032009-07-23 22:29:41 +000040// <rdar://problem/6335715> rule request: gets() buffer overflow
41// Part of recommendation: 300-BSI (buildsecurityin.us-cert.gov)
42char* gets(char *buf);
43
44void test_gets() {
45 char buff[1024];
46 gets(buff); // expected-warning{{Call to function 'gets' is extremely insecure as it can always result in a buffer overflow}}
47}
Ted Kremenekd032fcc2009-08-28 00:08:09 +000048
Zhongxing Xud6e7f9d2009-11-09 12:19:26 +000049int getpw(unsigned int uid, char *buf);
50
51void test_getpw() {
52 char buff[1024];
Ted Kremenek9bf9af92012-08-16 17:45:23 +000053 getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid()}}
Zhongxing Xud6e7f9d2009-11-09 12:19:26 +000054}
55
Ted Kremenekd032fcc2009-08-28 00:08:09 +000056// <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were
57// Dropped Successfully
58typedef unsigned int __uint32_t;
59typedef __uint32_t __darwin_uid_t;
60typedef __uint32_t __darwin_gid_t;
61typedef __darwin_uid_t uid_t;
62typedef __darwin_gid_t gid_t;
63int setuid(uid_t);
64int setregid(gid_t, gid_t);
65int setreuid(uid_t, uid_t);
66extern void check(int);
Eli Friedman53b3cde2009-12-16 06:28:21 +000067void abort(void);
Ted Kremenekd032fcc2009-08-28 00:08:09 +000068
69void test_setuid()
70{
71 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}}
72 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}}
73 if (setuid (2) != 0)
74 abort();
75
76 // Currently the 'setuid' check is not flow-sensitive, and only looks
77 // at whether the function was called in a compound statement. This
78 // will lead to false negatives, but there should be no false positives.
79 int t = setuid(2); // no-warning
80 (void)setuid (2); // no-warning
81
82 check(setuid (2)); // no-warning
83
84 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}}
85 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}}
86}
Ted Kremenekad5a6002009-09-02 02:47:41 +000087
88// <rdar://problem/6337100> CWE-338: Use of cryptographically weak prng
Reid Kleckner7f62b952013-06-24 16:56:16 +000089typedef unsigned short *ushort_ptr_t; // Test that sugar doesn't confuse the warning.
Ted Kremenekad5a6002009-09-02 02:47:41 +000090int rand(void);
91double drand48(void);
92double erand48(unsigned short[3]);
Reid Kleckner7f62b952013-06-24 16:56:16 +000093long jrand48(ushort_ptr_t);
Ted Kremenekad5a6002009-09-02 02:47:41 +000094void lcong48(unsigned short[7]);
95long lrand48(void);
96long mrand48(void);
97long nrand48(unsigned short[3]);
98long random(void);
99int rand_r(unsigned *);
100
101void test_rand()
102{
103 unsigned short a[7];
104 unsigned b;
105
106 rand(); // expected-warning{{Function 'rand' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
107 drand48(); // expected-warning{{Function 'drand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
108 erand48(a); // expected-warning{{Function 'erand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
109 jrand48(a); // expected-warning{{Function 'jrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
110 lcong48(a); // expected-warning{{Function 'lcong48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
111 lrand48(); // expected-warning{{Function 'lrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
112 mrand48(); // expected-warning{{Function 'mrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
113 nrand48(a); // expected-warning{{Function 'nrand48' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
114 rand_r(&b); // expected-warning{{Function 'rand_r' is obsolete because it implements a poor random number generator. Use 'arc4random' instead}}
115 random(); // expected-warning{{The 'random' function produces a sequence of values that an adversary may be able to predict. Use 'arc4random' instead}}
116}
Zhongxing Xuefd9ae82009-12-06 12:45:46 +0000117
118char *mktemp(char *buf);
119
120void test_mktemp() {
121 char *x = mktemp("/tmp/zxcv"); // expected-warning{{Call to function 'mktemp' is insecure as it always creates or uses insecure temporary file}}
122}
Lenny Maiorani6ffe7382011-03-31 22:09:14 +0000123
124
125//===----------------------------------------------------------------------===
126// strcpy()
127//===----------------------------------------------------------------------===
128#ifdef VARIANT
129
130#define __strcpy_chk BUILTIN(__strcpy_chk)
131char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
132
133#define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1)
134
135#else /* VARIANT */
136
137#define strcpy BUILTIN(strcpy)
138char *strcpy(char *restrict s1, const char *restrict s2);
139
140#endif /* VARIANT */
141
142void test_strcpy() {
143 char x[4];
144 char *y;
145
Ted Kremenek9bf9af92012-08-16 17:45:23 +0000146 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}}
Lenny Maiorani6ffe7382011-03-31 22:09:14 +0000147}
Lenny Maioranide909e42011-04-05 20:18:46 +0000148
149//===----------------------------------------------------------------------===
150// strcat()
151//===----------------------------------------------------------------------===
152#ifdef VARIANT
153
154#define __strcat_chk BUILTIN(__strcat_chk)
155char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
156
157#define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
158
159#else /* VARIANT */
160
161#define strcat BUILTIN(strcat)
162char *strcat(char *restrict s1, const char *restrict s2);
163
164#endif /* VARIANT */
165
166void test_strcat() {
167 char x[4];
168 char *y;
169
Ted Kremenek9bf9af92012-08-16 17:45:23 +0000170 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}}
Lenny Maioranide909e42011-04-05 20:18:46 +0000171}
Anna Zaksfedf5df2011-10-11 04:34:54 +0000172
173//===----------------------------------------------------------------------===
174// vfork()
175//===----------------------------------------------------------------------===
176typedef int __int32_t;
177typedef __int32_t pid_t;
Rafael Espindola5450f212011-10-19 14:50:34 +0000178pid_t vfork(void);
Anna Zaksfedf5df2011-10-11 04:34:54 +0000179
180void test_vfork() {
Ted Kremenek9bf9af92012-08-16 17:45:23 +0000181 vfork(); //expected-warning{{Call to function 'vfork' is insecure as it can lead to denial of service situations in the parent process}}
Anna Zaksfedf5df2011-10-11 04:34:54 +0000182}
Ted Kremenek89eaf8d2012-01-20 05:35:06 +0000183
184//===----------------------------------------------------------------------===
185// mkstemp()
186//===----------------------------------------------------------------------===
187
188char *mkdtemp(char *template);
189int mkstemps(char *template, int suffixlen);
190int mkstemp(char *template);
191char *mktemp(char *template);
192
193void test_mkstemp() {
194 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)}}
195 mkstemp("XXXXXX");
196 mkstemp("XXXXXXX");
197 mkstemps("XXXXXX", 0);
198 mkstemps("XXXXXX", 1); // expected-warning {{5 'X's seen}}
199 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)}}
200 mkdtemp("XX"); // expected-warning {{2 'X's seen}}
201 mkstemp("X"); // expected-warning {{Call to 'mkstemp' should have at least 6 'X's in the format string to be secure (1 'X' seen)}}
202 mkdtemp("XXXXXX");
203}
204