[PATCH] D27052: [compiler-rt][asan] Fix overlaping parameters for memmove/memcpy on windows.

Etienne Bergeron via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 23 08:28:30 PST 2016


etienneb created this revision.
etienneb added reviewers: rnk, zaks.anna.
etienneb added subscribers: llvm-commits, chrisha.
Herald added subscribers: dberris, kubabrecka.

On windows, memmove and memcpy may be the same functions (on 64-bits).

  -- f:\dd\vctools\crt\vcruntime\src\string\amd64\memcpy.asm --------------------
  
          OPTION PROLOGUE:NONE, EPILOGUE:NONE
  
          memmove = memcpy
          mov     r11, rcx                ; save destination address

This is causing ASAN to report overlaping parameters when instrumenting chromium.

  D:\src\chromium\src>out\asan64\chrome.exe --no-sandbox
  [8956:6208:1121/162511:ERROR:entry.cc(167)] Entry::Deserialize: dictionary has no interface_provider_specs key
  [8956:11560:1121/162511:ERROR:external_registry_loader_win.cc(130)] Missing value path for key Software\Google\Chrome\Ex
  tensions\doeiiacdhfmpdeckdaifnjaemmkkdlkf.
  =================================================================
  ==5132==ERROR: AddressSanitizer: memcpy-param-overlap: memory ranges [0x000000237ee8,0x000000237eea) and [0x000000237ee9
  , 0x000000237eeb) overlap

The error triggered on chromium:

  Child-SP          RetAddr           Call Site
  00000000`00166520 00000001`400a4886 chrome!__asan::ReportStringFunctionMemoryRangesOverlap+0x23 [d:\src\llvm\llvm\projects\compiler-rt\lib\asan\asan_report.cc @ 305]
  *** WARNING: Unable to verify checksum for D:\src\chromium\src\out\asan64dynamic\libglesv2.dll
  00000000`001672a0 000007fe`e1859607 chrome!__asan_wrap_memcpy+0xf6 [d:\src\llvm\llvm\projects\compiler-rt\lib\asan\asan_interceptors.cc @ 458]
  00000000`00167b30 000007fe`e184bcbc libglesv2!__acrt_fp_strflt_to_string+0xb7 [d:\th\minkernel\crts\ucrt\src\appcrt\convert\_fptostr.cpp @ 86]
  (Inline Function) --------`-------- libglesv2!fp_format_f+0x57 [d:\th\minkernel\crts\ucrt\src\appcrt\convert\cvt.cpp @ 578]
  00000000`00167b60 000007fe`e182e2a2 libglesv2!__acrt_fp_format+0x180 [d:\th\minkernel\crts\ucrt\src\appcrt\convert\cvt.cpp @ 722]
  00000000`00167bf0 000007fe`e182ce80 libglesv2!__crt_stdio_output::output_processor<char,__crt_stdio_output::stream_output_adapter<char>,__crt_stdio_output::format_validation_

This bug is similar to: https://llvm.org/bugs/show_bug.cgi?id=16362


https://reviews.llvm.org/D27052

Files:
  lib/asan/asan_interceptors.cc


Index: lib/asan/asan_interceptors.cc
===================================================================
--- lib/asan/asan_interceptors.cc
+++ lib/asan/asan_interceptors.cc
@@ -408,9 +408,27 @@
     return REAL(memcpy)(to, from, size);                                       \
   } while (0)
 
+#define ASAN_MEMMOVE_IMPL(ctx, to, from, size) do {                            \
+    if (UNLIKELY(!asan_inited))                                                \
+      return internal_memmove(to, from, size);                                 \
+    ENSURE_ASAN_INITED();                                                      \
+    if (flags()->replace_intrin) {                                             \
+      ASAN_READ_RANGE(ctx, from, size);                                        \
+      ASAN_WRITE_RANGE(ctx, to, size);                                         \
+    }                                                                          \
+    return internal_memmove(to, from, size);                                   \
+  } while (0)
 
 void *__asan_memcpy(void *to, const void *from, uptr size) {
+#if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
   ASAN_MEMCPY_IMPL(nullptr, to, from, size);
+#else
+  ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
+#endif
+}
+
+void *__asan_memmove(void *to, const void *from, uptr size) {
+  ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
 }
 
 // memset is called inside Printf.
@@ -430,21 +448,6 @@
   ASAN_MEMSET_IMPL(nullptr, block, c, size);
 }
 
-#define ASAN_MEMMOVE_IMPL(ctx, to, from, size) do {                            \
-    if (UNLIKELY(!asan_inited))                                                \
-      return internal_memmove(to, from, size);                                 \
-    ENSURE_ASAN_INITED();                                                      \
-    if (flags()->replace_intrin) {                                             \
-      ASAN_READ_RANGE(ctx, from, size);                                        \
-      ASAN_WRITE_RANGE(ctx, to, size);                                         \
-    }                                                                          \
-    return internal_memmove(to, from, size);                                   \
-  } while (0)
-
-void *__asan_memmove(void *to, const void *from, uptr size) {
-  ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
-}
-
 INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) {
   void *ctx;
   ASAN_INTERCEPTOR_ENTER(ctx, memmove);
@@ -454,7 +457,7 @@
 INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) {
   void *ctx;
   ASAN_INTERCEPTOR_ENTER(ctx, memcpy);
-#if !SANITIZER_MAC
+#if !SANITIZER_MAC && PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
   ASAN_MEMCPY_IMPL(ctx, to, from, size);
 #else
   // At least on 10.7 and 10.8 both memcpy() and memmove() are being replaced


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27052.79092.patch
Type: text/x-patch
Size: 2844 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161123/f90c1e29/attachment.bin>


More information about the llvm-commits mailing list