ramosian-glider / sanitizer-issues

test
0 stars 0 forks source link

libxpc is corrupting ASan flags on Mac OS 10.7 #53

Closed ramosian-glider closed 9 years ago

ramosian-glider commented 9 years ago

Originally reported on Google Code with ID 53

$ pwd
/Users/glider/src/asan/llvm/projects/compiler-rt/lib/asan
$ svn diff
Index: asan_rtl.cc
===================================================================
--- asan_rtl.cc (revision 152909)
+++ asan_rtl.cc (working copy)
@@ -32,7 +32,9 @@
 size_t FLAG_quarantine_size;
 int    FLAG_demangle;
 bool   FLAG_symbolize;
-int    FLAG_v;
+volatile int pad[1024];
+volatile int    FLAG_v;
+volatile int pad2[1024];
 int    FLAG_debug;
 bool   FLAG_poison_shadow;
 int    FLAG_report_globals;
@@ -412,6 +414,9 @@
   AsanDie();
 }

+extern "C"
+int mprotect(void *addr, size_t len, int prot);
+
 void __asan_init() {
   if (asan_inited) return;
   asan_init_is_running = true;
@@ -429,7 +434,8 @@
       IntFlagValue(options, "max_malloc_fill_size=", 0);

   FLAG_v = IntFlagValue(options, "verbosity=", 0);
-
+  Report("&FLAG_v=%p\n", &FLAG_v);
+  mprotect((void*)(((uintptr_t)(&FLAG_v) >> 12) << 12), 4096, /*PROT_READ*/ 0x1);
   FLAG_redzone = IntFlagValue(options, "redzone=",
       (ASAN_LOW_MEMORY) ? 64 : 128);
   CHECK(FLAG_redzone >= 32);
Index: asan_internal.h
===================================================================
--- asan_internal.h (revision 152909)
+++ asan_internal.h (working copy)
@@ -222,7 +222,7 @@
 extern size_t FLAG_quarantine_size;
 extern int    FLAG_demangle;
 extern bool   FLAG_symbolize;
-extern int    FLAG_v;
+extern volatile int    FLAG_v;
 extern size_t FLAG_redzone;
 extern int    FLAG_debug;
 extern bool   FLAG_poison_shadow;

$ ~/src/asan/llvm/build/Release+Asserts/bin/clang parseWebkit.m -o parseWebkit -framework
CoreFoundation -framework Foundation -framework WebKit -framework Cocoa -faddress-sanitizer
$ ./parseWebkit 1.html 2>&1 | tee log==13035== &FLAG_v=0x00010cc733f0
objc[13035]: Object 0x10d1e0388 of class __NSCFString autoreleased with no pool in
place - just leaking - break on objc_autoreleaseNoPool() to debug
objc[13035]: Object 0x10d1e0c80 of class NSConcreteData autoreleased with no pool in
place - just leaking - break on objc_autoreleaseNoPool() to debug
ASAN:SIGSEGV
==13035== ERROR: AddressSanitizer crashed on unknown address 0x00010cc733f0 (pc 0x7fffffd18053
sp 0x7fff6a80ee88 bp 0x7fff6a80f2d0 T0)
AddressSanitizer can not provide additional info. ABORTING
    #0 0x7fffffd18053
    #1 0x7fff85f9c416 (/usr/lib/system/libxpc.dylib+0x6416)
    #2 0x7fff85f9cd9a (/usr/lib/system/libxpc.dylib+0x6d9a)
    #3 0x7fff8b0accd8 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x4dcd8)
    #4 0x7fff8b0ac870 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x4d870)
    #5 0x7fff8b0ac7b1 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x4d7b1)
    #6 0x7fff8b0ac68a (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x4d68a)
    #7 0x7fff8b4a3224 (/usr/lib/system/libdispatch.dylib+0x5224)
    #8 0x7fff8b09b99a (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x3c99a)
    #9 0x7fff8b0dab58 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x7bb58)
    #10 0x7fff8b4a3224 (/usr/lib/system/libdispatch.dylib+0x5224)
    #11 0x7fff8b0a75da (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x485da)
    #12 0x7fff8b0b3b07 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x54b07)
    #13 0x7fff8b0b39e8 (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x549e8)
    #14 0x7fff8b0b398a (/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation+0x5498a)
    #15 0x7fff8c09a023 (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation+0xb023)
    #16 0x7fff8c099b51 (/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation+0xab51)
    #17 0x7fff81d7d1ad (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x1b1ad)
    #18 0x7fff81d7cf66 (/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit+0x1af66)
    #19 0x7fff84206662 (/usr/lib/libobjc.A.dylib+0xc662)
    #20 0x7fff8420655f (/usr/lib/libobjc.A.dylib+0xc55f)
    #21 0x7fff84206517 (/usr/lib/libobjc.A.dylib+0xc517)
    #22 0x7fff842062bb (/usr/lib/libobjc.A.dylib+0xc2bb)
    #23 0x7fff84203f3c (/usr/lib/libobjc.A.dylib+0x9f3c)
    #24 0x10ac14a50 (/Users/glider/src/./parseWebkit+0x3a50)
    #25 0x10ac12c84 (/Users/glider/src/./parseWebkit+0x1c84)
    #26 0x2
Stats: 0M malloced (0M for red zones) by 142 calls
Stats: 0M realloced by 4 calls
Stats: 0M freed by 46 calls
Stats: 0M really freed by 0 calls
Stats: 24M (6147 full pages) mmaped in 6 calls
  mmaps   by size class: 8:16383; 9:8191; 10:4095; 12:1024; 13:512; 14:256; 
  mallocs by size class: 8:126; 9:10; 10:2; 12:2; 13:1; 14:1; 
  frees   by size class: 8:39; 9:6; 13:1; 
  rfrees  by size class: 
Stats: malloc large: 0 small slow: 6

Apparently libxpc.dylib is trying to overwrite FLAG_v.

Reported by ramosian.glider on 2012-03-20 13:37:39

ramosian-glider commented 9 years ago
This is probably caused by mach_override incorrectly patching dispatch_async_f.

From gobjdump:
0000000000003939 <_dispatch_async_f>:
    3939:       83 7f 3c 01             cmpl   $0x1,0x3c(%rdi)
    393d:       74 4d                   je     398c <_dispatch_async_f+0x53>

From gdb:
(gdb) printf "%p\n", (void*)_ZN14__interception21real_dispatch_async_fE
0x7fffffd18000
(gdb) disas 0x7fffffd18000 0x7fffffd18020
Dump of assembler code from 0x7fffffd18000 to 0x7fffffd18020:
0x00007fffffd18000:     cmpl   $0x1,0x3c(%rdi)
0x00007fffffd18004:     je     0x7fffffd18053

The 2-byte je instruction is copied verbatim, so that becomes a wild jump into nowhere.
We'll need to somehow fix mach_override:
 -- it can patch both jump branches separately -- does not scale generally
 -- or it can copy the whole function so that every jump remains inside the function.

Maybe an ad-hoc solution for just dispatch_async_f will go.

Reported by ramosian.glider on 2012-03-21 16:38:21

ramosian-glider commented 9 years ago
Please remind why we need to intercept those beasts at all. 
yes, they create threads. Can we ignore it? 

Reported by konstantin.s.serebryany on 2012-03-21 16:46:44

ramosian-glider commented 9 years ago
The funny thing is that I've added those short jumps to the list of known instructions
myself, which was quite silly.
What I'm planning to do now is to expand short jumps into long ones when copying them
to the branch island.
I consider disabling any interceptors conceptually wrong. The interception mechanism
is broken, so we need to fix it rather than disable code that depends on it.

Reported by ramosian.glider on 2012-03-22 08:54:11

ramosian-glider commented 9 years ago
LLVM r153249 should fix this issue. Both 32-bit and 64-bit ASan tests pass for me on
Lion (modulo HugeMallocTest, for which the memory limit should be tuned).

Reported by ramosian.glider on 2012-03-22 11:56:31

ramosian-glider commented 9 years ago
Adding Project:AddressSanitizer as part of GitHub migration.

Reported by ramosian.glider on 2015-07-30 09:12:58