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,17 @@ 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, to_size) \ + { \ + AsanInterceptorContext *_ctx = (AsanInterceptorContext *)ctx; \ + uptr from_size = Min(to_size, MaybeRealStrnlen(from, to_size) + 1); \ + if (_ctx) { \ + CHECK_RANGES_OVERLAP(_ctx->interceptor_name, to, from_size, from, \ + from_size); \ + } \ + ASAN_READ_RANGE(ctx, from, from_size); \ + ASAN_WRITE_RANGE(ctx, to, Min(from_size, 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/strlcat_test.cpp b/compiler-rt/test/asan/TestCases/Posix/strlcat_test.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Posix/strlcat_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 + +void overflow() { + const char src[] = "1234567890"; + char dst[7] = {'x', 'y', 'z', 0}; + size_t len; + + strlcat(dst, src, sizeof(dst) + 1); + // CHECK-OVERFLOW: stack-buffer-overflow +} + +void overlap() { + const int dst_size = 10; + char src[dst_size] = {'a', 'b', 'c', 0}; + strlcat(src, src, dst_size); // 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 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,35 @@ +// 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 + +void overflow() { + const char *src = "@@@@plz_copy_me@@@@"; + const int dst_size = 3; + char dst[dst_size]; + strlcpy(dst, src, dst_size + 1); + // CHECK-OVERFLOW: stack-buffer-overflow +} + +void overlap() { + const int dst_size = 10; + char src[dst_size] = "123456789"; + strlcpy(src, src, dst_size); // 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