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 4 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 9 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 14 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 19 20#ifdef USE_BUILTINS 21# define BUILTIN(f) __builtin_ ## f 22#else /* USE_BUILTINS */ 23# define BUILTIN(f) f 24#endif /* USE_BUILTINS */ 25 26#include "Inputs/system-header-simulator-for-valist.h" 27#include "Inputs/system-header-simulator-for-simple-stream.h" 28 29typedef typeof(sizeof(int)) size_t; 30 31 32// rule request: floating point used as loop condition (FLP30-C, FLP-30-CPP) 33// 34// For reference: https://www.securecoding.cert.org/confluence/display/seccode/FLP30-C.+Do+not+use+floating+point+variables+as+loop+counters 35// 36void 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'}} 50} 51 52// Obsolete function bcmp 53int bcmp(const void *, const void *, size_t); 54 55int test_bcmp(void *a, void *b, size_t n) { 56 return bcmp(a, b, n); // expected-warning{{The bcmp() function is obsoleted by memcmp()}} 57} 58 59// Obsolete function bcopy 60void bcopy(const void *, void *, size_t); 61 62void 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(}} 64} 65 66// Obsolete function bzero 67void bzero(void *, size_t); 68 69void test_bzero(void *a, size_t n) { 70 bzero(a, n); // expected-warning{{The bzero() function is obsoleted by memset()}} 71} 72 73// rule request: gets() buffer overflow 74// Part of recommendation: 300-BSI (buildsecurityin.us-cert.gov) 75char* gets(char *buf); 76 77void 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}} 80} 81 82int getpw(unsigned int uid, char *buf); 83 84void 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()}} 87} 88 89// CWE-273: Failure to Check Whether Privileges Were Dropped Successfully 90typedef unsigned int __uint32_t; 91typedef __uint32_t __darwin_uid_t; 92typedef __uint32_t __darwin_gid_t; 93typedef __darwin_uid_t uid_t; 94typedef __darwin_gid_t gid_t; 95int setuid(uid_t); 96int setregid(gid_t, gid_t); 97int setreuid(uid_t, uid_t); 98extern void check(int); 99void abort(void); 100 101void test_setuid(void) 102{ 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(); 107 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 113 114 check(setuid (2)); // no-warning 115 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}} 118} 119 120// CWE-338: Use of cryptographically weak prng 121typedef unsigned short *ushort_ptr_t; // Test that sugar doesn't confuse the warning. 122int rand(void); 123double drand48(void); 124double erand48(unsigned short[3]); 125long jrand48(ushort_ptr_t); 126void lcong48(unsigned short[7]); 127long lrand48(void); 128long mrand48(void); 129long nrand48(unsigned short[3]); 130long random(void); 131int rand_r(unsigned *); 132 133void test_rand(void) 134{ 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}} 148} 149 150char *mktemp(char *buf); 151 152void 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}} 154} 155 156 157//===----------------------------------------------------------------------=== 158// strcpy() 159//===----------------------------------------------------------------------=== 160#ifdef VARIANT 161 162#define __strcpy_chk BUILTIN(__strcpy_chk) 163char *__strcpy_chk(char *restrict s1, const char *restrict s2, size_t destlen); 164 165#define strcpy(a,b) __strcpy_chk(a,b,(size_t)-1) 166 167#else /* VARIANT */ 168 169#define strcpy BUILTIN(strcpy) 170char *strcpy(char *restrict s1, const char *restrict s2); 171 172#endif /* VARIANT */ 173 174void test_strcpy(void) { 175 char x[4]; 176 char *y; 177 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}} 179} 180 181void 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}} 184} 185 186void test_strcpy_safe(void) { 187 char x[5]; 188 strcpy(x, "abcd"); 189} 190 191void test_strcpy_safe_2(void) { 192 struct {char s1[100];} s; 193 strcpy(s.s1, "hello"); 194} 195 196//===----------------------------------------------------------------------=== 197// strcat() 198//===----------------------------------------------------------------------=== 199#ifdef VARIANT 200 201#define __strcat_chk BUILTIN(__strcat_chk) 202char *__strcat_chk(char *restrict s1, const char *restrict s2, size_t destlen); 203 204#define strcat(a,b) __strcat_chk(a,b,(size_t)-1) 205 206#else /* VARIANT */ 207 208#define strcat BUILTIN(strcat) 209char *strcat(char *restrict s1, const char *restrict s2); 210 211#endif /* VARIANT */ 212 213void test_strcat(void) { 214 char x[4]; 215 char *y; 216 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}} 218} 219 220//===----------------------------------------------------------------------=== 221// vfork() 222//===----------------------------------------------------------------------=== 223typedef int __int32_t; 224typedef __int32_t pid_t; 225pid_t vfork(void); 226 227void 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}} 229} 230 231//===----------------------------------------------------------------------=== 232// mkstemp() 233//===----------------------------------------------------------------------=== 234 235char *mkdtemp(char *template); 236int mkstemps(char *template, int suffixlen); 237int mkstemp(char *template); 238char *mktemp(char *template); 239 240void 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"); 250} 251 252 253//===----------------------------------------------------------------------=== 254// deprecated or unsafe buffer handling 255//===----------------------------------------------------------------------=== 256typedef int wchar_t; 257 258int sprintf(char *str, const char *format, ...); 259//int vsprintf (char *s, const char *format, va_list arg); 260int scanf(const char *format, ...); 261int wscanf(const wchar_t *format, ...); 262int fscanf(FILE *stream, const char *format, ...); 263int fwscanf(FILE *stream, const wchar_t *format, ...); 264int vscanf(const char *format, va_list arg); 265int vwscanf(const wchar_t *format, va_list arg); 266int vfscanf(FILE *stream, const char *format, va_list arg); 267int vfwscanf(FILE *stream, const wchar_t *format, va_list arg); 268int sscanf(const char *s, const char *format, ...); 269int swscanf(const wchar_t *ws, const wchar_t *format, ...); 270int vsscanf(const char *s, const char *format, va_list arg); 271int vswscanf(const wchar_t *ws, const wchar_t *format, va_list arg); 272int swprintf(wchar_t *ws, size_t len, const wchar_t *format, ...); 273int snprintf(char *s, size_t n, const char *format, ...); 274int vswprintf(wchar_t *ws, size_t len, const wchar_t *format, va_list arg); 275int vsnprintf(char *s, size_t n, const char *format, va_list arg); 276void *memcpy(void *destination, const void *source, size_t num); 277void *memmove(void *destination, const void *source, size_t num); 278char *strncpy(char *destination, const char *source, size_t num); 279char *strncat(char *destination, const char *source, size_t num); 280void *memset(void *ptr, int value, size_t num); 281 282void 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}} 307} 308 309void 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}} 319} 320 321void 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}} 330} 331