[compiler-rt] [compiler-rt][asan] intercept bsd's strtoq. (PR #78097)
via llvm-commits
llvm-commits at lists.llvm.org
Sun Jan 14 06:19:35 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: David CARLIER (devnexen)
<details>
<summary>Changes</summary>
---
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
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;
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/78097
More information about the llvm-commits
mailing list