333 lines · c
1// RUN: %clang_analyze_cc1 \2// RUN: -analyzer-checker=security.cert.env.InvalidPtr\3// RUN: -analyzer-config security.cert.env.InvalidPtr:InvalidatingGetEnv=true \4// RUN: -analyzer-output=text -verify -Wno-unused %s5 6#include "../Inputs/system-header-simulator.h"7char *getenv(const char *name);8char *setlocale(int category, const char *locale);9char *strerror(int errnum);10 11typedef struct {12 char * field;13} lconv;14lconv *localeconv(void);15 16typedef struct {17} tm;18char *asctime(const tm *timeptr);19 20int strcmp(const char*, const char*);21extern void foo(char *e);22extern char* bar(void);23 24 25void getenv_test1(void) {26 char *p;27 28 p = getenv("VAR");29 *p; // no-warning30 31 p = getenv("VAR2");32 *p; // no-warning, getenv result was assigned to the same pointer33}34 35void getenv_test2(void) {36 char *p, *p2;37 38 p = getenv("VAR");39 // expected-note@-1{{previous function call was here}}40 *p; // no-warning41 42 p2 = getenv("VAR2");43 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}44 45 *p;46 // expected-warning@-1{{dereferencing an invalid pointer}}47 // expected-note@-2{{dereferencing an invalid pointer}}48}49 50void getenv_test3(void) {51 char *p, *p2, *p3;52 53 p = getenv("VAR");54 *p; // no-warning55 56 p = getenv("VAR2");57 // expected-note@-1{{previous function call was here}}58 p2 = getenv("VAR2");59 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}60 61 p3 = getenv("VAR3");62 63 *p;64 // expected-warning@-1{{dereferencing an invalid pointer}}65 // expected-note@-2{{dereferencing an invalid pointer}}66}67 68void getenv_test4(void) {69 char *p, *p2, *p3;70 71 p = getenv("VAR");72 // expected-note@-1{{previous function call was here}}73 p2 = getenv("VAR2");74 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}75 p3 = getenv("VAR3");76 77 *p;78 // expected-warning@-1{{dereferencing an invalid pointer}}79 // expected-note@-2{{dereferencing an invalid pointer}}80}81 82void getenv_test5(void) {83 char *p, *p2, *p3;84 85 p = getenv("VAR");86 p2 = getenv("VAR2");87 // expected-note@-1{{previous function call was here}}88 p3 = getenv("VAR3");89 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}90 91 *p2;92 // expected-warning@-1{{dereferencing an invalid pointer}}93 // expected-note@-2{{dereferencing an invalid pointer}}94}95 96void getenv_test6(void) {97 char *p, *p2;98 p = getenv("VAR");99 *p; // no-warning100 101 p = getenv("VAR2");102 // expected-note@-1{{previous function call was here}}103 *p; // no-warning104 105 p2 = getenv("VAR3");106 // expected-note@-1{{previous function call was here}}107 // expected-note@-2{{'getenv' call may invalidate the result of the previous 'getenv'}}108 109 *p;110 // expected-warning@-1{{dereferencing an invalid pointer}}111 // expected-note@-2{{dereferencing an invalid pointer}}112 113 *p2; // no-warning114 115 p = getenv("VAR4");116 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}117 118 *p; // no-warning119 *p2;120 // expected-warning@-1{{dereferencing an invalid pointer}}121 // expected-note@-2{{dereferencing an invalid pointer}}122}123 124void getenv_test7(void) {125 char *p, *p2;126 p = getenv("VAR");127 // expected-note@-1{{previous function call was here}}128 *p; // no-warning129 130 p2 = getenv("VAR2");131 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}132 133 foo(p);134 // expected-warning@-1{{use of invalidated pointer 'p' in a function call}}135 // expected-note@-2{{use of invalidated pointer 'p' in a function call}}136}137 138void getenv_test8(void) {139 static const char *array[] = {140 0,141 0,142 "/var/tmp",143 "/usr/tmp",144 "/tmp",145 "."146 };147 148 if( !array[0] )149 // expected-note@-1{{Taking true branch}}150 array[0] = getenv("TEMPDIR");151 // expected-note@-1{{previous function call was here}}152 153 if( !array[1] )154 // expected-note@-1{{Taking true branch}}155 array[1] = getenv("TMPDIR");156 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}157 158 *array[0];159 // expected-warning@-1{{dereferencing an invalid pointer}}160 // expected-note@-2{{dereferencing an invalid pointer}}161}162 163void getenv_test9(void) {164 char *p, *p2;165 p = getenv("something");166 p = bar();167 p2 = getenv("something");168 *p; // no-warning: p does not point to getenv anymore169}170 171void getenv_test10(void) {172 strcmp(getenv("VAR1"), getenv("VAR2"));173 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}174 // expected-note@-2{{previous function call was here}}175 // expected-warning@-3{{use of invalidated pointer 'getenv("VAR1")' in a function call}}176 // expected-note@-4{{use of invalidated pointer 'getenv("VAR1")' in a function call}}177}178 179void dereference_pointer(char* a) {180 *a;181 // expected-warning@-1{{dereferencing an invalid pointer}}182 // expected-note@-2{{dereferencing an invalid pointer}}183}184 185void getenv_test11(void) {186 char *p = getenv("VAR");187 // expected-note@-1{{previous function call was here}}188 189 char *pp = getenv("VAR2");190 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}191 192 dereference_pointer(p);193 // expected-note@-1{{Calling 'dereference_pointer'}}194}195 196void getenv_test12(int flag1, int flag2) {197 char *p = getenv("VAR");198 // expected-note@-1{{previous function call was here}}199 200 if (flag1) {201 // expected-note@-1{{Assuming 'flag1' is not equal to 0}}202 // expected-note@-2{{Taking true branch}}203 char *pp = getenv("VAR2");204 // expected-note@-1{{'getenv' call may invalidate the result of the previous 'getenv'}}205 }206 207 if (flag2) {208 // expected-note@-1{{Assuming 'flag2' is not equal to 0}}209 // expected-note@-2{{Taking true branch}}210 *p;211 // expected-warning@-1{{dereferencing an invalid pointer}}212 // expected-note@-2{{dereferencing an invalid pointer}}213 }214}215 216void setlocale_test1(void) {217 char *p, *p2;218 p = setlocale(0, "VAR");219 *p; // no-warning220 221 p = setlocale(0, "VAR2");222 // expected-note@-1{{previous function call was here}}223 *p; // no-warning224 225 p2 = setlocale(0, "VAR3");226 // expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}227 228 *p;229 // expected-warning@-1{{dereferencing an invalid pointer}}230 // expected-note@-2{{dereferencing an invalid pointer}}231}232 233void setlocale_test2(int flag) {234 char *p, *p2;235 p = setlocale(0, "VAR");236 *p; // no-warning237 238 p = setlocale(0, "VAR2");239 // expected-note@-1{{previous function call was here}}240 *p; // no-warning241 242 if (flag) {243 // expected-note@-1{{Assuming 'flag' is not equal to 0}}244 // expected-note@-2{{Taking true branch}}245 p2 = setlocale(0, "VAR3");246 // expected-note@-1{{'setlocale' call may invalidate the result of the previous 'setlocale'}}247 }248 249 *p;250 // expected-warning@-1{{dereferencing an invalid pointer}}251 // expected-note@-2{{dereferencing an invalid pointer}}252}253 254void strerror_test1(void) {255 char *p, *p2;256 257 p = strerror(0);258 *p; // no-warning259 260 p = strerror(1);261 // expected-note@-1{{previous function call was here}}262 *p; // no-warning263 264 p2 = strerror(2);265 // expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}266 267 *p;268 // expected-warning@-1{{dereferencing an invalid pointer}}269 // expected-note@-2{{dereferencing an invalid pointer}}270}271 272void strerror_test2(int errno) {273 char *p, *p2;274 275 p = strerror(0);276 *p; // no-warning277 278 p = strerror(1);279 // expected-note@-1{{previous function call was here}}280 *p; // no-warning281 282 if (0 == 1) {283 // expected-note@-1{{0 is not equal to 1}}284 // expected-note@-2{{Taking false branch}}285 p2 = strerror(2);286 }287 288 *p; // no-warning289 290 if (errno) {291 // expected-note@-1{{Assuming 'errno' is not equal to 0}}292 // expected-note@-2{{Taking true branch}}293 p2 = strerror(errno);294 // expected-note@-1{{'strerror' call may invalidate the result of the previous 'strerror'}}295 }296 297 *p;298 // expected-warning@-1{{dereferencing an invalid pointer}}299 // expected-note@-2{{dereferencing an invalid pointer}}300}301 302void asctime_test(void) {303 const tm *t;304 const tm *tt;305 306 char* p = asctime(t);307 // expected-note@-1{{previous function call was here}}308 char* pp = asctime(tt);309 // expected-note@-1{{'asctime' call may invalidate the result of the previous 'asctime'}}310 311 *p;312 // expected-warning@-1{{dereferencing an invalid pointer}}313 // expected-note@-2{{dereferencing an invalid pointer}}314}315 316void localeconv_test1(void) {317 lconv *lc1 = localeconv();318 // expected-note@-1{{previous function call was here}}319 lconv *lc2 = localeconv();320 // expected-note@-1{{'localeconv' call may invalidate the result of the previous 'localeconv'}}321 322 *lc1;323 // expected-warning@-1{{dereferencing an invalid pointer}}324 // expected-note@-2{{dereferencing an invalid pointer}}325}326 327void localeconv_test2(void) {328 // TODO: false negative329 lconv *lc1 = localeconv();330 lconv *lc2 = localeconv();331 lc1->field;332}333