[compiler-rt] b5e7f95 - [msan] Check qsort input.

Evgenii Stepanov via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 6 15:07:17 PST 2020


Author: Evgenii Stepanov
Date: 2020-01-06T15:07:02-08:00
New Revision: b5e7f95cfbeb28ff8b966a2b7e38a03f32410030

URL: https://github.com/llvm/llvm-project/commit/b5e7f95cfbeb28ff8b966a2b7e38a03f32410030
DIFF: https://github.com/llvm/llvm-project/commit/b5e7f95cfbeb28ff8b966a2b7e38a03f32410030.diff

LOG: [msan] Check qsort input.

Summary:
Qsort interceptor suppresses all checks by unpoisoning the data in the
wrapper of a comparator function, and then unpoisoning the output array
as well.

This change adds an explicit run of the comparator on all elements of
the input array to catch any sanitizer bugs.

Reviewers: vitalybuka

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D71780

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
    compiler-rt/test/msan/qsort.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 8f365ee30854..47e344c9e3f2 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 eb8697011867..cf754012b228 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);


        


More information about the llvm-commits mailing list