diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -96,6 +96,14 @@ ASAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver) #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ ASAN_WRITE_RANGE(ctx, ptr, size) +#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) { \ + AsanInterceptorContext *_ctx = (AsanInterceptorContext *)ctx; \ + if (_ctx) { \ + CHECK_RANGES_OVERLAP(_ctx->interceptor_name, to, size, from, size); \ + }\ + ASAN_READ_RANGE(ctx, from, size); \ + ASAN_WRITE_RANGE(ctx, to, size); \ +} #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ ASAN_READ_RANGE(ctx, ptr, size) #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ diff --git a/compiler-rt/test/asan/TestCases/Posix/strlcpy_test.cpp b/compiler-rt/test/asan/TestCases/Posix/strlcpy_test.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Posix/strlcpy_test.cpp @@ -0,0 +1,36 @@ +// UNSUPPORTED: linux + +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: not %run %t overflow 2>&1 | FileCheck --check-prefix=CHECK-OVERFLOW %s +// RUN: not %run %t overlap 2>&1 | FileCheck --check-prefix=CHECK-OVERLAP %s + +#include +#include +#include +#include + +#define ARRAY_SIZE(X) sizeof(X) / sizeof(X[0]) + +void overflow() { + const char src[] = "@@@@plz_copy_me@@@@"; + char *buffer = (char *)malloc(1); // Too small + strlcpy(buffer, src, ARRAY_SIZE(src)); // BOOM + // CHECK-OVERFLOW: heap-buffer-overflow + free(buffer); +} + +void overlap() { + char src[] = "@@@@plz_copy_me@@@@"; + strlcpy(src, src, ARRAY_SIZE(src)); // BOOM + // CHECK-OVERLAP: strlcpy-param-overlap +} + +int main(int argc, char **argv) { + assert(argc == 2); + if (!strcmp(argv[1], "overflow")) { + overflow(); + } else if (!strcmp(argv[1], "overlap")) { + overlap(); + } + return 0; +} \ No newline at end of file