xref: /aosp_15_r20/external/clang/test/Analysis/security-syntax-checks.m (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
2*67e74705SXin Li// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
3*67e74705SXin Li// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
4*67e74705SXin Li// RUN: %clang_cc1 -triple i386-apple-darwin10 -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
5*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
6*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DUSE_BUILTINS -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
7*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
8*67e74705SXin Li// RUN: %clang_cc1 -triple x86_64-unknown-cloudabi -analyze -DUSE_BUILTINS -DVARIANT -analyzer-checker=security.insecureAPI,security.FloatLoopCounter %s -verify
9*67e74705SXin Li
10*67e74705SXin Li#ifdef USE_BUILTINS
11*67e74705SXin Li# define BUILTIN(f) __builtin_ ## f
12*67e74705SXin Li#else /* USE_BUILTINS */
13*67e74705SXin Li# define BUILTIN(f) f
14*67e74705SXin Li#endif /* USE_BUILTINS */
15*67e74705SXin Li
16*67e74705SXin Litypedef typeof(sizeof(int)) size_t;
17*67e74705SXin Li
18*67e74705SXin Li
19*67e74705SXin Li// <rdar://problem/6336718> rule request: floating point used as loop
20*67e74705SXin Li//  condition (FLP30-C, FLP-30-CPP)
21*67e74705SXin Li//
22*67e74705SXin Li// For reference: https://www.securecoding.cert.org/confluence/display/seccode/FLP30-C.+Do+not+use+floating+point+variables+as+loop+counters
23*67e74705SXin Li//
24*67e74705SXin Livoid test_float_condition() {
25*67e74705SXin Li  for (float x = 0.1f; x <= 1.0f; x += 0.1f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
26*67e74705SXin Li  for (float x = 100000001.0f; x <= 100000010.0f; x += 1.0f) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
27*67e74705SXin Li  for (float x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'float'}}
28*67e74705SXin Li  for (double x = 100000001.0; x <= 100000010.0; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
29*67e74705SXin Li  for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++ ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
30*67e74705SXin Li
31*67e74705SXin Li  for (double x = 100000001.0; 100000010.0 >= x; x = x + 1.0 ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
32*67e74705SXin Li
33*67e74705SXin Li  int i = 0;
34*67e74705SXin Li  for (double x = 100000001.0; ((x)) <= 100000010.0; ((x))++, ++i ) {} // expected-warning{{Variable 'x' with floating point type 'double'}}
35*67e74705SXin Li
36*67e74705SXin Li  typedef float FooType;
37*67e74705SXin Li  for (FooType x = 100000001.0f; x <= 100000010.0f; x++ ) {} // expected-warning{{Variable 'x' with floating point type 'FooType'}}
38*67e74705SXin Li}
39*67e74705SXin Li
40*67e74705SXin Li// <rdar://problem/6335715> rule request: gets() buffer overflow
41*67e74705SXin Li// Part of recommendation: 300-BSI (buildsecurityin.us-cert.gov)
42*67e74705SXin Lichar* gets(char *buf);
43*67e74705SXin Li
44*67e74705SXin Livoid test_gets() {
45*67e74705SXin Li  char buff[1024];
46*67e74705SXin Li  gets(buff); // expected-warning{{Call to function 'gets' is extremely insecure as it can always result in a buffer overflow}}
47*67e74705SXin Li}
48*67e74705SXin Li
49*67e74705SXin Liint getpw(unsigned int uid, char *buf);
50*67e74705SXin Li
51*67e74705SXin Livoid test_getpw() {
52*67e74705SXin Li  char buff[1024];
53*67e74705SXin Li  getpw(2, buff); // expected-warning{{The getpw() function is dangerous as it may overflow the provided buffer. It is obsoleted by getpwuid()}}
54*67e74705SXin Li}
55*67e74705SXin Li
56*67e74705SXin Li// <rdar://problem/6337132> CWE-273: Failure to Check Whether Privileges Were
57*67e74705SXin Li//  Dropped Successfully
58*67e74705SXin Litypedef unsigned int __uint32_t;
59*67e74705SXin Litypedef __uint32_t __darwin_uid_t;
60*67e74705SXin Litypedef __uint32_t __darwin_gid_t;
61*67e74705SXin Litypedef __darwin_uid_t uid_t;
62*67e74705SXin Litypedef __darwin_gid_t gid_t;
63*67e74705SXin Liint setuid(uid_t);
64*67e74705SXin Liint setregid(gid_t, gid_t);
65*67e74705SXin Liint setreuid(uid_t, uid_t);
66*67e74705SXin Liextern void check(int);
67*67e74705SXin Livoid abort(void);
68*67e74705SXin Li
69*67e74705SXin Livoid test_setuid()
70*67e74705SXin Li{
71*67e74705SXin Li  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*67e74705SXin Li  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*67e74705SXin Li  if (setuid (2) != 0)
74*67e74705SXin Li    abort();
75*67e74705SXin Li
76*67e74705SXin Li  // Currently the 'setuid' check is not flow-sensitive, and only looks
77*67e74705SXin Li  // at whether the function was called in a compound statement.  This
78*67e74705SXin Li  // will lead to false negatives, but there should be no false positives.
79*67e74705SXin Li  int t = setuid(2);  // no-warning
80*67e74705SXin Li  (void)setuid (2); // no-warning
81*67e74705SXin Li
82*67e74705SXin Li  check(setuid (2)); // no-warning
83*67e74705SXin Li
84*67e74705SXin Li  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*67e74705SXin Li  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*67e74705SXin Li}
87*67e74705SXin Li
88*67e74705SXin Li// <rdar://problem/6337100> CWE-338: Use of cryptographically weak prng
89*67e74705SXin Litypedef  unsigned short *ushort_ptr_t;  // Test that sugar doesn't confuse the warning.
90*67e74705SXin Liint      rand(void);
91*67e74705SXin Lidouble   drand48(void);
92*67e74705SXin Lidouble   erand48(unsigned short[3]);
93*67e74705SXin Lilong     jrand48(ushort_ptr_t);
94*67e74705SXin Livoid     lcong48(unsigned short[7]);
95*67e74705SXin Lilong     lrand48(void);
96*67e74705SXin Lilong     mrand48(void);
97*67e74705SXin Lilong     nrand48(unsigned short[3]);
98*67e74705SXin Lilong     random(void);
99*67e74705SXin Liint      rand_r(unsigned *);
100*67e74705SXin Li
101*67e74705SXin Livoid test_rand()
102*67e74705SXin Li{
103*67e74705SXin Li  unsigned short a[7];
104*67e74705SXin Li  unsigned b;
105*67e74705SXin Li
106*67e74705SXin Li  rand();	// expected-warning{{Function 'rand' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
107*67e74705SXin Li  drand48();	// expected-warning{{Function 'drand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
108*67e74705SXin Li  erand48(a);	// expected-warning{{Function 'erand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
109*67e74705SXin Li  jrand48(a);	// expected-warning{{Function 'jrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
110*67e74705SXin Li  lcong48(a);	// expected-warning{{Function 'lcong48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
111*67e74705SXin Li  lrand48();	// expected-warning{{Function 'lrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
112*67e74705SXin Li  mrand48();	// expected-warning{{Function 'mrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
113*67e74705SXin Li  nrand48(a);	// expected-warning{{Function 'nrand48' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
114*67e74705SXin Li  rand_r(&b);	// expected-warning{{Function 'rand_r' is obsolete because it implements a poor random number generator.  Use 'arc4random' instead}}
115*67e74705SXin Li  random();	// expected-warning{{The 'random' function produces a sequence of values that an adversary may be able to predict.  Use 'arc4random' instead}}
116*67e74705SXin Li}
117*67e74705SXin Li
118*67e74705SXin Lichar *mktemp(char *buf);
119*67e74705SXin Li
120*67e74705SXin Livoid test_mktemp() {
121*67e74705SXin Li  char *x = mktemp("/tmp/zxcv"); // expected-warning{{Call to function 'mktemp' is insecure as it always creates or uses insecure temporary file}}
122*67e74705SXin Li}
123*67e74705SXin Li
124*67e74705SXin Li
125*67e74705SXin Li//===----------------------------------------------------------------------===
126*67e74705SXin Li// strcpy()
127*67e74705SXin Li//===----------------------------------------------------------------------===
128*67e74705SXin Li#ifdef VARIANT
129*67e74705SXin Li
130*67e74705SXin Li#define __strcpy_chk BUILTIN(__strcpy_chk)
131*67e74705SXin Lichar *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen);
132*67e74705SXin Li
133*67e74705SXin Li#define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1)
134*67e74705SXin Li
135*67e74705SXin Li#else /* VARIANT */
136*67e74705SXin Li
137*67e74705SXin Li#define strcpy BUILTIN(strcpy)
138*67e74705SXin Lichar *strcpy(char *restrict s1, const char *restrict s2);
139*67e74705SXin Li
140*67e74705SXin Li#endif /* VARIANT */
141*67e74705SXin Li
142*67e74705SXin Livoid test_strcpy() {
143*67e74705SXin Li  char x[4];
144*67e74705SXin Li  char *y;
145*67e74705SXin Li
146*67e74705SXin Li  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}}
147*67e74705SXin Li}
148*67e74705SXin Li
149*67e74705SXin Li//===----------------------------------------------------------------------===
150*67e74705SXin Li// strcat()
151*67e74705SXin Li//===----------------------------------------------------------------------===
152*67e74705SXin Li#ifdef VARIANT
153*67e74705SXin Li
154*67e74705SXin Li#define __strcat_chk BUILTIN(__strcat_chk)
155*67e74705SXin Lichar *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen);
156*67e74705SXin Li
157*67e74705SXin Li#define strcat(a,b) __strcat_chk(a,b,(size_t)-1)
158*67e74705SXin Li
159*67e74705SXin Li#else /* VARIANT */
160*67e74705SXin Li
161*67e74705SXin Li#define strcat BUILTIN(strcat)
162*67e74705SXin Lichar *strcat(char *restrict s1, const char *restrict s2);
163*67e74705SXin Li
164*67e74705SXin Li#endif /* VARIANT */
165*67e74705SXin Li
166*67e74705SXin Livoid test_strcat() {
167*67e74705SXin Li  char x[4];
168*67e74705SXin Li  char *y;
169*67e74705SXin Li
170*67e74705SXin Li  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}}
171*67e74705SXin Li}
172*67e74705SXin Li
173*67e74705SXin Li//===----------------------------------------------------------------------===
174*67e74705SXin Li// vfork()
175*67e74705SXin Li//===----------------------------------------------------------------------===
176*67e74705SXin Litypedef int __int32_t;
177*67e74705SXin Litypedef __int32_t pid_t;
178*67e74705SXin Lipid_t vfork(void);
179*67e74705SXin Li
180*67e74705SXin Livoid test_vfork() {
181*67e74705SXin Li  vfork(); //expected-warning{{Call to function 'vfork' is insecure as it can lead to denial of service situations in the parent process}}
182*67e74705SXin Li}
183*67e74705SXin Li
184*67e74705SXin Li//===----------------------------------------------------------------------===
185*67e74705SXin Li// mkstemp()
186*67e74705SXin Li//===----------------------------------------------------------------------===
187*67e74705SXin Li
188*67e74705SXin Lichar *mkdtemp(char *template);
189*67e74705SXin Liint mkstemps(char *template, int suffixlen);
190*67e74705SXin Liint mkstemp(char *template);
191*67e74705SXin Lichar *mktemp(char *template);
192*67e74705SXin Li
193*67e74705SXin Livoid test_mkstemp() {
194*67e74705SXin Li  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*67e74705SXin Li  mkstemp("XXXXXX");
196*67e74705SXin Li  mkstemp("XXXXXXX");
197*67e74705SXin Li  mkstemps("XXXXXX", 0);
198*67e74705SXin Li  mkstemps("XXXXXX", 1); // expected-warning {{5 'X's seen}}
199*67e74705SXin Li  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*67e74705SXin Li  mkdtemp("XX"); // expected-warning {{2 'X's seen}}
201*67e74705SXin Li  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*67e74705SXin Li  mkdtemp("XXXXXX");
203*67e74705SXin Li}
204*67e74705SXin Li
205