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