Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -226,11 +226,10 @@ #ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL #define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \ COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \ - uptr from_length = internal_strnlen(s, size); \ - uptr copy_length = Min(size, from_length); \ + uptr copy_length = internal_strnlen(s, size); \ char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \ if (common_flags()->intercept_strndup) { \ - COMMON_INTERCEPTOR_READ_RANGE(ctx, s, copy_length + 1); \ + 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); \ Index: test/asan/TestCases/Posix/strndup_no_null_test.cc =================================================================== --- /dev/null +++ test/asan/TestCases/Posix/strndup_no_null_test.cc @@ -0,0 +1,22 @@ +// RUN: %clang_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clang_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clang_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s +// RUN: %clang_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s + +// When built as C on Linux, strndup is transformed to __strndup. +// RUN: %clang_asan -O3 -xc %s -o %t && not %run %t 2>&1 | FileCheck %s + +// Unwind problem on arm: "main" is missing from the allocation stack trace. +// UNSUPPORTED: win32,s390,armv7l-unknown-linux-gnueabihf + +#include + +char kChars[] = {'f', 'o', 'o'}; + +int main(int argc, char **argv) { + char *copy = strndup(kChars, 3); + copy = strndup(kChars, 10); + // CHECK: AddressSanitizer: global-buffer-overflow + // CHECK: {{.*}}main {{.*}}strndup_no_null_test.cc:[[@LINE-2]] + return *copy; +}