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