Skip to content

Conversation

@devnexen
Copy link
Member

No description provided.

@llvmbot
Copy link
Member

llvmbot commented Jan 14, 2024

@llvm/pr-subscribers-compiler-rt-sanitizer

Author: David CARLIER (devnexen)

Changes

Full diff: https://github.com/llvm/llvm-project/pull/78097.diff

2 Files Affected:

  • (modified) compiler-rt/lib/asan/asan_interceptors.cpp (+4)
  • (added) compiler-rt/test/asan/TestCases/FreeBSD/strtoq_strict.c (+122)
diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp index 4de2fa356374a6..eeb475bc5c03db 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -635,6 +635,10 @@ INTERCEPTOR_STRTO_BASE(long, __isoc23_strtol) INTERCEPTOR_STRTO_BASE(long long, __isoc23_strtoll) # endif +# if SANITIZER_FREEBSD || SANITIZER_NETBSD +INTERCEPTOR_STRTO_BASE(u64, strtoq) +# endif + INTERCEPTOR(int, atoi, const char *nptr) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, atoi); diff --git a/compiler-rt/test/asan/TestCases/FreeBSD/strtoq_strict.c b/compiler-rt/test/asan/TestCases/FreeBSD/strtoq_strict.c new file mode 100644 index 00000000000000..0890225b7b87a4 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/FreeBSD/strtoq_strict.c @@ -0,0 +1,122 @@ +// Test strict_string_checks option in strtoq function +// RUN: %clang_asan %s -o %t +// RUN: %run %t test1 2>&1 +// RUN: %env_asan_opts=strict_string_checks=false %run %t test1 2>&1 +// RUN: %env_asan_opts=strict_string_checks=true not %run %t test1 2>&1 | FileCheck %s --check-prefix=CHECK1 +// RUN: %run %t test2 2>&1 +// RUN: %env_asan_opts=strict_string_checks=false %run %t test2 2>&1 +// RUN: %env_asan_opts=strict_string_checks=true not %run %t test2 2>&1 | FileCheck %s --check-prefix=CHECK2 +// RUN: %run %t test3 2>&1 +// RUN: %env_asan_opts=strict_string_checks=false %run %t test3 2>&1 +// RUN: %env_asan_opts=strict_string_checks=true not %run %t test3 2>&1 | FileCheck %s --check-prefix=CHECK3 +// RUN: %run %t test4 2>&1 +// RUN: %env_asan_opts=strict_string_checks=false %run %t test4 2>&1 +// RUN: %env_asan_opts=strict_string_checks=true not %run %t test4 2>&1 | FileCheck %s --check-prefix=CHECK4 +// RUN: %run %t test5 2>&1 +// RUN: %env_asan_opts=strict_string_checks=false %run %t test5 2>&1 +// RUN: %env_asan_opts=strict_string_checks=true not %run %t test5 2>&1 | FileCheck %s --check-prefix=CHECK5 +// RUN: %run %t test6 2>&1 +// RUN: %env_asan_opts=strict_string_checks=false %run %t test6 2>&1 +// RUN: %env_asan_opts=strict_string_checks=true not %run %t test6 2>&1 | FileCheck %s --check-prefix=CHECK6 +// RUN: %run %t test7 2>&1 +// RUN: %env_asan_opts=strict_string_checks=false %run %t test7 2>&1 +// RUN: %env_asan_opts=strict_string_checks=true not %run %t test7 2>&1 | FileCheck %s --check-prefix=CHECK7 + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <sanitizer/asan_interface.h> + +#if __LP64__ +typedef long long quad_t; +#else +typedef long quad_t; +#endif + +void test1(char *array, char *endptr) { + // Buffer overflow if there is no terminating null (depends on base) + quad_t r = strtoq(array, &endptr, 3); + assert(array + 2 == endptr); + assert(r == 5); +} + +void test2(char *array, char *endptr) { + // Buffer overflow if there is no terminating null (depends on base) + array[2] = 'z'; + quad_t r = strtoq(array, &endptr, 35); + assert(array + 2 == endptr); + assert(r == 37); +} + +void test3(char *array, char *endptr) { + // Buffer overflow if base is invalid. + memset(array, 0, 8); + ASAN_POISON_MEMORY_REGION(array, 8); + quad_t r = strtoq(array + 1, NULL, -1); + assert(r == 0); + ASAN_UNPOISON_MEMORY_REGION(array, 8); +} + +void test4(char *array, char *endptr) { + // Buffer overflow if base is invalid. + quad_t r = strtoq(array + 3, NULL, 1); + assert(r == 0); +} + +void test5(char *array, char *endptr) { + // Overflow if no digits are found. + array[0] = ' '; + array[1] = '+'; + array[2] = '-'; + quad_t r = strtoq(array, NULL, 0); + assert(r == 0); +} + +void test6(char *array, char *endptr) { + // Overflow if no digits are found. + array[0] = ' '; + array[1] = array[2] = 'z'; + quad_t r = strtoq(array, &endptr, 0); + assert(array == endptr); + assert(r == 0); +} + +void test7(char *array, char *endptr) { + // Overflow if no digits are found. + array[2] = 'z'; + quad_t r = strtoq(array + 2, NULL, 0); + assert(r == 0); +} + +int main(int argc, char **argv) { + char *array0 = (char*)malloc(11); + char* array = array0 + 8; + char *endptr = NULL; + array[0] = '1'; + array[1] = '2'; + array[2] = '3'; + if (argc != 2) return 1; + if (!strcmp(argv[1], "test1")) test1(array, endptr); + // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK1: READ of size 4 + if (!strcmp(argv[1], "test2")) test2(array, endptr); + // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK2: READ of size 4 + if (!strcmp(argv[1], "test3")) test3(array0, endptr); + // CHECK3: {{.*ERROR: AddressSanitizer: use-after-poison on address}} + // CHECK3: READ of size 1 + if (!strcmp(argv[1], "test4")) test4(array, endptr); + // CHECK4: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK4: READ of size 1 + if (!strcmp(argv[1], "test5")) test5(array, endptr); + // CHECK5: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK5: READ of size 4 + if (!strcmp(argv[1], "test6")) test6(array, endptr); + // CHECK6: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK6: READ of size 4 + if (!strcmp(argv[1], "test7")) test7(array, endptr); + // CHECK7: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} + // CHECK7: READ of size 2 + free(array0); + return 0; +} 
@github-actions
Copy link

github-actions bot commented Jan 14, 2024

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 59e79f0de59d9e4576b6bf562de40a914702efd4 a96671f793ea390cf651badfbedfa81ffe77b936 -- compiler-rt/test/asan/TestCases/FreeBSD/strtoq_strict.c compiler-rt/lib/asan/asan_interceptors.cpp
View the diff from clang-format here.
diff --git a/compiler-rt/test/asan/TestCases/FreeBSD/strtoq_strict.c b/compiler-rt/test/asan/TestCases/FreeBSD/strtoq_strict.c index d12bae17f7..7e9b891071 100644 --- a/compiler-rt/test/asan/TestCases/FreeBSD/strtoq_strict.c +++ b/compiler-rt/test/asan/TestCases/FreeBSD/strtoq_strict.c @@ -23,9 +23,9 @@ // RUN: %env_asan_opts=strict_string_checks=true not %run %t test7 2>&1 | FileCheck %s --check-prefix=CHECK7 #include <assert.h> +#include <sanitizer/asan_interface.h> #include <stdlib.h> #include <string.h> -#include <sanitizer/asan_interface.h> void test1(char *array, char *endptr) { // Buffer overflow if there is no terminating null (depends on base) @@ -83,32 +83,40 @@ void test7(char *array, char *endptr) { } int main(int argc, char **argv) { - char *array0 = (char*)malloc(11); - char* array = array0 + 8; + char *array0 = (char *)malloc(11); + char *array = array0 + 8; char *endptr = NULL; array[0] = '1'; array[1] = '2'; array[2] = '3'; - if (argc != 2) return 1; - if (!strcmp(argv[1], "test1")) test1(array, endptr); + if (argc != 2) + return 1; + if (!strcmp(argv[1], "test1")) + test1(array, endptr); // CHECK1: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} // CHECK1: READ of size 4 - if (!strcmp(argv[1], "test2")) test2(array, endptr); + if (!strcmp(argv[1], "test2")) + test2(array, endptr); // CHECK2: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} // CHECK2: READ of size 4 - if (!strcmp(argv[1], "test3")) test3(array0, endptr); + if (!strcmp(argv[1], "test3")) + test3(array0, endptr); // CHECK3: {{.*ERROR: AddressSanitizer: use-after-poison on address}} // CHECK3: READ of size 1 - if (!strcmp(argv[1], "test4")) test4(array, endptr); + if (!strcmp(argv[1], "test4")) + test4(array, endptr); // CHECK4: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} // CHECK4: READ of size 1 - if (!strcmp(argv[1], "test5")) test5(array, endptr); + if (!strcmp(argv[1], "test5")) + test5(array, endptr); // CHECK5: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} // CHECK5: READ of size 4 - if (!strcmp(argv[1], "test6")) test6(array, endptr); + if (!strcmp(argv[1], "test6")) + test6(array, endptr); // CHECK6: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} // CHECK6: READ of size 4 - if (!strcmp(argv[1], "test7")) test7(array, endptr); + if (!strcmp(argv[1], "test7")) + test7(array, endptr); // CHECK7: {{.*ERROR: AddressSanitizer: heap-buffer-overflow on address}} // CHECK7: READ of size 2 free(array0); 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment