[compiler-rt] ddf897f - [msan] Check qsort input.
Evgenii Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 20 12:42:19 PST 2019
Author: Evgenii Stepanov
Date: 2019-12-20T12:41:57-08:00
New Revision: ddf897fc80499ece298bc33201db6b697d2af50e
URL: https://github.com/llvm/llvm-project/commit/ddf897fc80499ece298bc33201db6b697d2af50e
DIFF: https://github.com/llvm/llvm-project/commit/ddf897fc80499ece298bc33201db6b697d2af50e.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 2d9636a9c879..68a9db5bba7b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -9665,6 +9665,15 @@ 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; ++i) {
+ void *p = (void *)((char *)base + i * size);
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
+ // Compare each element with itself to trigger an equality check, which
+ // typically requires the comparator to look as many of the object fields as
+ // possible.
+ compar(p, p);
+ }
qsort_compar_f old_compar = qsort_compar;
qsort_compar = compar;
SIZE_T old_size = qsort_size;
@@ -9694,6 +9703,15 @@ 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; ++i) {
+ void *p = (void *)((char *)base + i * size);
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ // Compare each element with itself to trigger an equality check, which
+ // typically requires the comparator to look as many of the object fields as
+ // possible.
+ compar(p, p, 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