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