diff options
Diffstat (limited to 'compiler-rt')
-rw-r--r-- | compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc | 14 | ||||
-rw-r--r-- | compiler-rt/test/msan/qsort.cpp | 5 |
2 files changed, 19 insertions, 0 deletions
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 8f365ee3085..47e344c9e3f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -9670,6 +9670,13 @@ INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size, qsort_compar_f compar) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar); + // Run the comparator over all array elements to detect any memory issues. + for (SIZE_T i = 0; i < nmemb - 1; ++i) { + void *p = (void *)((char *)base + i * size); + void *q = (void *)((char *)base + (i + 1) * size); + COMMON_INTERCEPTOR_UNPOISON_PARAM(2); + compar(p, q); + } qsort_compar_f old_compar = qsort_compar; qsort_compar = compar; SIZE_T old_size = qsort_size; @@ -9699,6 +9706,13 @@ INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size, qsort_r_compar_f compar, void *arg) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg); + // Run the comparator over all array elements to detect any memory issues. + for (SIZE_T i = 0; i < nmemb - 1; ++i) { + void *p = (void *)((char *)base + i * size); + void *q = (void *)((char *)base + (i + 1) * size); + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + compar(p, q, arg); + } qsort_r_compar_f old_compar = qsort_r_compar; qsort_r_compar = compar; SIZE_T old_size = qsort_r_size; diff --git a/compiler-rt/test/msan/qsort.cpp b/compiler-rt/test/msan/qsort.cpp index eb869701186..cf754012b22 100644 --- a/compiler-rt/test/msan/qsort.cpp +++ b/compiler-rt/test/msan/qsort.cpp @@ -1,4 +1,5 @@ // RUN: %clangxx_msan -O0 -g %s -o %t && %run %t +// RUN: %clangxx_msan -DPOISON -O0 -g %s -o %t && not %run %t 2>&1 | FileCheck %s #include <assert.h> #include <errno.h> @@ -65,6 +66,10 @@ int main(int argc, char *argv[]) { for (int i = 0; i < kSize1; ++i) p[i] = i * 2 + (i % 3 - 1) * 3; poison_stack_and_param(); +#ifdef POISON + __msan_poison(p + 1, sizeof(long)); + // CHECK: Uninitialized bytes in __msan_check_mem_is_initialized at offset 0 inside [{{.*}}, 8) +#endif qsort(p, kSize1, sizeof(long), compar1); __msan_check_mem_is_initialized(p, sizeof(long) * kSize1); assert(seen2); |