1// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 2// XFAIL: android 3// 4// RUN: %clangxx_asan -O0 %s -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s 5// RUN: %clangxx_asan -O1 %s -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s 6// RUN: %clangxx_asan -O2 %s -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s 7// RUN: %clangxx_asan -O3 %s -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s 8// 9// RUN: %clangxx_asan -O0 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s 10// RUN: %clangxx_asan -O1 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s 11// RUN: %clangxx_asan -O2 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s 12// RUN: %clangxx_asan -O3 %s -D_FILE_OFFSET_BITS=64 -DTEMP_DIR='"'"%T"'"' -o %t && %run %t 2>&1 | FileCheck %s 13 14#include <dirent.h> 15#include <memory.h> 16#include <stdio.h> 17#include <stdlib.h> 18#include <unistd.h> 19 20 21int main() { 22 // Ensure the readdir_r interceptor doesn't erroneously mark the entire dirent 23 // as written when the end of the directory pointer is reached. 24 fputs("test1: reading the " TEMP_DIR " directory...\n", stderr); 25 DIR *d = opendir(TEMP_DIR); 26 struct dirent *result = (struct dirent *)(0xfeedbeef); 27 // We assume the temp dir for this test doesn't have crazy long file names. 28 char entry_buffer[4096]; 29 memset(entry_buffer, 0xab, sizeof(entry_buffer)); 30 unsigned count = 0; 31 do { 32 // Stamp the entry struct to try to trick the interceptor. 33 ((struct dirent *)entry_buffer)->d_reclen = 9999; 34 if (readdir_r(d, (struct dirent *)entry_buffer, &result) != 0) 35 abort(); 36 ++count; 37 } while (result != NULL); 38 fprintf(stderr, "read %d entries\n", count); 39 closedir(d); 40 // CHECK: test1: reading the {{.*}} directory... 41 // CHECK-NOT: stack-buffer-overflow 42 // CHECK: read {{.*}} entries 43 44 // Ensure the readdir64_r interceptor doesn't have the bug either. 45 fputs("test2: reading the " TEMP_DIR " directory...\n", stderr); 46 d = opendir(TEMP_DIR); 47 struct dirent64 *result64; 48 memset(entry_buffer, 0xab, sizeof(entry_buffer)); 49 count = 0; 50 do { 51 // Stamp the entry struct to try to trick the interceptor. 52 ((struct dirent64 *)entry_buffer)->d_reclen = 9999; 53 if (readdir64_r(d, (struct dirent64 *)entry_buffer, &result64) != 0) 54 abort(); 55 ++count; 56 } while (result64 != NULL); 57 fprintf(stderr, "read %d entries\n", count); 58 closedir(d); 59 // CHECK: test2: reading the {{.*}} directory... 60 // CHECK-NOT: stack-buffer-overflow 61 // CHECK: read {{.*}} entries 62} 63