diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -5978,6 +5978,9 @@ if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end) COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base, fp->_IO_read_end - fp->_IO_read_base); + if (fp->_IO_write_base && fp->_IO_write_base < fp->_IO_write_end) + COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_write_base, + fp->_IO_write_end - fp->_IO_write_base); #endif #endif // SANITIZER_HAS_STRUCT_FILE } @@ -6204,6 +6207,8 @@ INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp); + if (fp) + unpoison_file(fp); int res = REAL(fflush)(fp); // FIXME: handle fp == NULL if (fp) { @@ -6223,6 +6228,8 @@ COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp); COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); const FileMetadata *m = GetInterceptorMetadata(fp); + if (fp) + unpoison_file(fp); int res = REAL(fclose)(fp); if (m) { COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); diff --git a/compiler-rt/test/msan/Linux/file.cpp b/compiler-rt/test/msan/Linux/file.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/msan/Linux/file.cpp @@ -0,0 +1,29 @@ +// RUN: %clangxx_msan -std=c++11 -O0 %s -o %t && %run %t +// RUN: %clangxx_msan -std=c++11 -fsanitize-memory-track-origins -O0 %s -o %t && %run %t + +#include +#include + +#include + +int main(int argc, char *argv[]) { + FILE *f = fopen(argv[0], "r"); + assert(f); + char buf[50]; + fread(buf, 1, 1, f); + fflush(f); + + assert(f->_IO_read_end > f->_IO_read_base); + __msan_check_mem_is_initialized(f->_IO_read_end, f->_IO_read_end - f->_IO_read_base); + + char tmp_file[1000]; + sprintf(tmp_file, "%s.write.tmp", argv[0]); + + f = fopen(tmp_file, "w+"); + assert(f); + fwrite(buf, 1, 1, f); + fflush(f); + + assert(f->_IO_write_end > f->_IO_write_base); + __msan_check_mem_is_initialized(f->_IO_write_end, f->_IO_write_end - f->_IO_write_base); +}