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 @@ -385,9 +385,11 @@ if (common_flags()->intercept_strndup) { \ COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \ } \ - COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \ - internal_memcpy(new_mem, s, copy_length); \ - new_mem[copy_length] = '\0'; \ + if (new_mem) { \ + COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \ + internal_memcpy(new_mem, s, copy_length); \ + new_mem[copy_length] = '\0'; \ + } \ return new_mem; #endif diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/decorate_proc_maps.cpp b/compiler-rt/test/sanitizer_common/TestCases/Linux/decorate_proc_maps.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/Linux/decorate_proc_maps.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/decorate_proc_maps.cpp @@ -12,7 +12,7 @@ #include #include -bool CopyFdToFd(int in_fd, int out_fd) { +int CopyFdToFd(int in_fd, int out_fd) { const size_t kBufSize = 0x10000; static char buf[kBufSize]; while (true) { @@ -23,18 +23,23 @@ break; } else if (errno != EAGAIN || errno != EWOULDBLOCK || errno != EINTR) { fprintf(stderr, "error reading file, errno %d\n", errno); - return false; + return 1; } } - return true; + return 0; } void *ThreadFn(void *arg) { (void)arg; int fd = open("/proc/self/maps", O_RDONLY); - bool res = CopyFdToFd(fd, 2); - close(fd); - return (void *)!res; + if (fd >= 0) { + int res = CopyFdToFd(fd, 2); + close(fd); + return (void *)res; + } else { + fprintf(stderr, "error opening file, errno %d\n", errno); + return (void*)1; + } } int main(void) { diff --git a/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp b/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp --- a/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp +++ b/compiler-rt/test/sanitizer_common/TestCases/max_allocation_size.cpp @@ -35,6 +35,10 @@ // RUN: | FileCheck %s --check-prefix=CHECK-nnCRASH // RUN: %env_tool_opts=max_allocation_size_mb=2:allocator_may_return_null=1 \ // RUN: %run %t new-nothrow 2>&1 | FileCheck %s --check-prefix=CHECK-NULL +// RUN: %env_tool_opts=max_allocation_size_mb=2:allocator_may_return_null=0 \ +// RUN: not %run %t strndup 2>&1 | FileCheck %s --check-prefix=CHECK-sCRASH +// RUN: %env_tool_opts=max_allocation_size_mb=2:allocator_may_return_null=1 \ +// RUN: %run %t strndup 2>&1 | FileCheck %s --check-prefix=CHECK-NULL // win32 is disabled due to failing errno tests. // UNSUPPORTED: ubsan, windows-msvc @@ -47,6 +51,8 @@ #include #include +constexpr size_t MaxAllocationSize = size_t{2} << 20; + static void *allocate(const char *Action, size_t Size) { if (!strcmp(Action, "malloc")) return malloc(Size); @@ -65,12 +71,21 @@ return ::operator new(Size); if (!strcmp(Action, "new-nothrow")) return ::operator new(Size, std::nothrow); + if (!strcmp(Action, "strndup")) + { + static char pstr[MaxAllocationSize+1] = {'a'}; + for (size_t i=0; i