1 // RUN: %clangxx_asan -g %s -o %t 2 // RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-FGETS 3 // RUN: not %run %t 2 2>&1 | FileCheck %s --check-prefix=CHECK-FPUTS 4 // RUN: not %run %t 3 2>&1 | FileCheck %s --check-prefix=CHECK-PUTS 5 6 #include <assert.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 test_fgets(const char * testfile)11int test_fgets(const char *testfile) { 12 char buf[2]; 13 FILE *fp = fopen(testfile, "r"); 14 assert(fp); 15 fgets(buf, sizeof(buf) + 1, fp); // BOOM 16 fclose(fp); 17 return 0; 18 } 19 test_fputs()20int test_fputs() { 21 char buf[1] = {'x'}; // Note: not nul-terminated 22 FILE *fp = fopen("/dev/null", "w"); 23 assert(fp); 24 fputs(buf, fp); // BOOM 25 fclose(fp); 26 return 0; 27 } 28 test_puts()29int test_puts() { 30 char *p = strdup("x"); 31 free(p); 32 puts(p); // BOOM 33 return 0; 34 } 35 main(int argc,char * argv[])36int main(int argc, char *argv[]) { 37 assert(argc >= 2); 38 int testno = argv[1][0] - '0'; 39 if (testno == 1) { 40 return test_fgets(argv[0]); 41 } 42 if (testno == 2) 43 return test_fputs(); 44 if (testno == 3) 45 return test_puts(); 46 return 1; 47 } 48 49 // CHECK-FGETS: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}} 50 // CHECK-FGETS: #{{.*}} in {{(wrap_|__interceptor_)?}}fgets 51 // CHECK-FPUTS: {{.*ERROR: AddressSanitizer: stack-buffer-overflow}} 52 // CHECK-FPUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}fputs 53 // CHECK-PUTS: {{.*ERROR: AddressSanitizer: heap-use-after-free}} 54 // CHECK-PUTS: #{{.*}} in {{(wrap_|__interceptor_)?}}puts 55