[compiler-rt] change write order of frexpl & frexpf so it doesn't corrupt stack ids
authorEmily Shi <code@emi.sh>
Fri, 25 Jun 2021 20:32:03 +0000 (13:32 -0700)
committerEmily Shi <code@emi.sh>
Fri, 16 Jul 2021 17:58:12 +0000 (10:58 -0700)
This was fixed in the past for `frexp`, but was not made for `frexpl` & `frexpf` https://github.com/google/sanitizers/issues/321
This patch copies the fix over to `frexpl` because it caused `frexp_interceptor.cpp` test to fail on iPhone and `frexpf` for consistency.

rdar://79652161

Reviewed By: delcypher, vitalybuka

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

compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp [new file with mode: 0644]
compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp [new file with mode: 0644]

index ea0d03e..d099978 100644 (file)
@@ -957,6 +957,7 @@ INTERCEPTOR(double, frexp, double x, int *exp) {
   // Assuming frexp() always writes to |exp|.
   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
   double res = REAL(frexp)(x, exp);
+  COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
   return res;
 }
 
@@ -969,22 +970,18 @@ INTERCEPTOR(double, frexp, double x, int *exp) {
 INTERCEPTOR(float, frexpf, float x, int *exp) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
-  // FIXME: under ASan the call below may write to freed memory and corrupt
-  // its metadata. See
-  // https://github.com/google/sanitizers/issues/321.
-  float res = REAL(frexpf)(x, exp);
   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
+  float res = REAL(frexpf)(x, exp);
+  COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
   return res;
 }
 
 INTERCEPTOR(long double, frexpl, long double x, int *exp) {
   void *ctx;
   COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
-  // FIXME: under ASan the call below may write to freed memory and corrupt
-  // its metadata. See
-  // https://github.com/google/sanitizers/issues/321.
-  long double res = REAL(frexpl)(x, exp);
   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
+  long double res = REAL(frexpl)(x, exp);
+  COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
   return res;
 }
 
diff --git a/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp b/compiler-rt/test/asan/TestCases/frexpf_interceptor.cpp
new file mode 100644 (file)
index 0000000..91da09a
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// Test the frexpf() interceptor.
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+int main() {
+  float x = 3.14;
+  int *exp = (int *)malloc(sizeof(int));
+  free(exp);
+  double y = frexpf(x, exp);
+  // CHECK: use-after-free
+  // CHECK: SUMMARY
+  return 0;
+}
diff --git a/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp b/compiler-rt/test/asan/TestCases/frexpl_interceptor.cpp
new file mode 100644 (file)
index 0000000..46bb6a2
--- /dev/null
@@ -0,0 +1,16 @@
+// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// Test the frexpl() interceptor.
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+int main() {
+  long double x = 3.14;
+  int *exp = (int *)malloc(sizeof(int));
+  free(exp);
+  double y = frexpl(x, exp);
+  // CHECK: use-after-free
+  // CHECK: SUMMARY
+  return 0;
+}