ramosian-glider / sanitizers

0 stars 0 forks source link

Infinite recursion in the dynamic runtime on 10.8 #117

Open ramosian-glider opened 9 years ago

ramosian-glider commented 9 years ago

Originally reported on Google Code with ID 116

On a 10.7 machine:

$ cat t.c 
#include <stdlib.h>
int main() { 
free((void*)0x1234567);
 return 0; }

$ build/Release+Asserts/bin/clang -faddress-sanitizer t.c -o t  -v                

clang version 3.2 (trunk 165105) (llvm/trunk 165119)
Target: x86_64-apple-darwin11.4.2
Thread model: posix
 "/Users/glider/src/asan/llvm/build/Release+Asserts/bin/clang" -cc1 -triple x86_64-apple-macosx10.7.0
-emit-obj -mrelax-all -disable-free -main-file-name t.c -pic-level 2 -mdisable-fp-elim
-masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 133.3 -v -resource-dir
/Users/glider/src/asan/llvm/build/Release+Asserts/bin/../lib/clang/3.2 -fmodule-cache-path
/var/folders/00/0k0r8000h01000cxqpysvccm002831/T/clang-module-cache -fdebug-compilation-dir
/Users/glider/src/asan/llvm -ferror-limit 19 -fmessage-length 186 -faddress-sanitizer
-stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.7.0 -fobjc-dispatch-method=mixed
-fobjc-default-synthesize-properties -fdiagnostics-show-option -fcolor-diagnostics
-o /var/folders/00/0k0r8000h01000cxqpysvccm002831/T/t-t64Sky.o -x c t.c
clang -cc1 version 3.2 based upon LLVM 3.2svn default target x86_64-apple-darwin11.4.2
ignoring nonexistent directory "/usr/local/include"
#include "..." search starts here:
#include <...> search starts here:
 /Users/glider/src/asan/llvm/build/Release+Asserts/bin/../lib/clang/3.2/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.
 "/usr/llvm-gcc-4.2/libexec/gcc/i686-apple-darwin11/4.2.1/ld" -demangle -dynamic -arch
x86_64 -macosx_version_min 10.7.0 -o t -lcrt1.10.6.o /var/folders/00/0k0r8000h01000cxqpysvccm002831/T/t-t64Sky.o
/Users/glider/src/asan/llvm/build/Release+Asserts/bin/../lib/clang/3.2/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
-lstdc++ -framework CoreFoundation -lSystem /Users/glider/src/asan/llvm/build/Release+Asserts/bin/../lib/clang/3.2/lib/darwin/libclang_rt.osx.a

$ otool -L /Users/glider/src/asan/llvm/build/Release+Asserts/bin/../lib/clang/3.2/lib/darwin/libclang_rt.asan_osx_dynamic.dylib
/Users/glider/src/asan/llvm/build/Release+Asserts/bin/../lib/clang/3.2/lib/darwin/libclang_rt.asan_osx_dynamic.dylib:
    @loader_path/libclang_rt.asan_osx_dynamic.dylib (compatibility version 0.0.0, current
version 0.0.0)
    /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (compatibility
version 300.0.0, current version 833.25.0)
    /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 52.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 159.1.0)
    /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility
version 150.0.0, current version 635.21.0)

On a 10.6 machine:

$ ./t
==4833== AddressSanitizer CHECK failed: /Users/glider/src/asan/llvm/projects/compiler-rt/lib/sanitizer_common/sanitizer_mac.cc:99
"((env_ptr)) != (0)" (0x0, 0x0)
Stats: 0M malloced (0M for red zones) by 0 calls
Stats: 0M realloced by 0 calls
Stats: 0M freed by 0 calls
Stats: 0M really freed by 0 calls
Stats: 0M (0 full pages) mmaped in 0 calls
  mmaps   by size class: 
  mallocs by size class: 
  frees   by size class: 
  rfrees  by size class: 
Stats: malloc large: 0 small slow: 0

Reported by ramosian.glider on 2012-10-03 16:45:33

ramosian-glider commented 9 years ago
10.7 again:
$ ./t
ASAN:SIGSEGV
=================================================================
==52310== ERROR: AddressSanitizer crashed on unknown address 0x00000123455f (pc 0x00010c07fddc
sp 0x7fff6bc70300 bp 0x7fff6bc70b30 T0)
AddressSanitizer can not provide additional info.
    #0 0x10c07fddb (/Users/glider/src/asan/llvm/./libclang_rt.asan_osx_dynamic.dylib+0x8ddb)
    #1 0x10c071e67 (/Users/glider/src/asan/llvm/./t+0x100000e67)
    #2 0x10c071d73 (/Users/glider/src/asan/llvm/./t+0x100000d73)
    #3 0x0
Stats: 0M malloced (0M for red zones) by 0 calls
Stats: 0M realloced by 0 calls
Stats: 0M freed by 0 calls
Stats: 0M really freed by 0 calls
Stats: 0M (0 full pages) mmaped in 0 calls
  mmaps   by size class: 
  mallocs by size class: 
  frees   by size class: 
  rfrees  by size class: 
Stats: malloc large: 0 small slow: 0
==52310== ABORTING

Reported by ramosian.glider on 2012-10-03 16:46:24

ramosian-glider commented 9 years ago
On a 10.8 machine:

$ ./t
ASAN:SIGSEGV
=================================================================
==87734== ERROR: AddressSanitizer crashed on unknown address 0x00000123455f (pc 0x00010000bddc
sp 0x7fff5fbff3c0 bp 0x7fff5fbffbf0 T0)
AddressSanitizer can not provide additional info.
    #0 0x10000bddb (/Users/glider/./libclang_rt.asan_osx_dynamic.dylib+0x8ddb)
    #1 0x100000e67 (/Users/glider/./t+0x100000e67)
    #2 0x100000d53 (/Users/glider/./t+0x100000d53)
    #3 0x0 (/Users/glider/./t+0x0)
Segmentation fault: 11

Reported by ramosian.glider on 2012-10-03 16:48:30

ramosian-glider commented 9 years ago
This has nothing to do with copying the files to other machines, i.e. the test really
behaves this way when built on 10.6 and 10.8.
I've opened issue 117 to track the CHECK failure from _NSGetEnviron() on 10.6, so let
the current issue remain for the segfault on 10.8

Reported by ramosian.glider on 2012-10-04 12:40:55

ramosian-glider commented 9 years ago

Reported by ramosian.glider on 2012-10-04 12:41:11

ramosian-glider commented 9 years ago
The problem is not ASan-specific and is related to resolver function interposition being
broken on Mac.
# ===========================================
$ cat t.c
#include <stdlib.h>

void *moomove(void *s1, void *s2, size_t n) {
  return memmove(s1, s2, n);
}

size_t moolen(const char *s) {
  return strlen(s);
}

int main() { 
 volatile int a[20];
 a[0] = moolen("Hello");
 moomove(&a[0], &a[10], 2);
 return 0;
}
# ===========================================
$ cat v.cc
#include <unistd.h>
#include <string.h>

size_t my_strlen(const char *s) {
//  write(2, "strlen\n", 7);
  return strlen(s);
}

void *my_memmove(void *s1, const void *s2, size_t n) {
//  write(2, "memmove\n", 8);
  return memmove(s1, s2, n);
}

struct interpose_substitution {
  const void* replacement;
  const void* original;
};

#define INTERPOSE_FUNCTION(function) \
    { reinterpret_cast<const void*>(my_##function), \
      reinterpret_cast<const void*>(function) }

__attribute__((used))
const interpose_substitution substitutions[]
    __attribute__((section("__DATA, __interpose"))) = {
  INTERPOSE_FUNCTION(strlen),
  INTERPOSE_FUNCTION(memmove),
};
# ===========================================
# v.dylib is an library that interposes strlen() and memmove()
$ g++ v.cc -dynamiclib -o v.dylib
# t is a program that calls strlen() and memmove()
$ gcc t.c -o t v.dylib -w
$ DYLD_INSERT_LIBRARIES=`pwd`/v.dylib ./t
Segmentation fault: 11

This actually happens because of the infinite recursion in my_memmove()
$  gdb t
(gdb) set env DYLD_INSERT_LIBRARIES=/Users/glider/src/asan/llvm/interp/v.dylib
(gdb) set start-with-shell 0
(gdb) r
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00007fff5f3ffff8
0x0000000100003eea in my_memmove ()
...
#2976 0x0000000100003eef in my_memmove ()
#2977 0x0000000100003eef in my_memmove ()
#2978 0x0000000100003eef in my_memmove ()

Reported by ramosian.glider on 2012-10-15 14:38:17

ramosian-glider commented 9 years ago

Reported by ramosian.glider on 2012-10-15 15:33:53

ramosian-glider commented 9 years ago
This is a bug in the interposition of resolver functions (radar://12455091).
As a temporary solution the wrappers for such functions (e.g. memmove) now call our
own implementations (e.g. internal_memmove).

Another solution from Nick Kledzik is to make a call via a pointer to the original
function:

void (*pMemcpy)(void *, const void *, uptr n) = &memcpy;

void *internal_memcpy(void *dest, const void *src, uptr n) {
  // stuff
  return (*pMemcpy)(dest, src, n);
}

Reported by ramosian.glider on 2012-10-29 11:30:33

ramosian-glider commented 9 years ago
They say the problem is fixed in 10.9. We'll need to revisit this bug when we stop supporting
10.8 (around the time 10.10 is out)

Reported by ramosian.glider on 2014-05-07 09:08:03

ramosian-glider commented 9 years ago

Reported by ramosian.glider on 2015-07-30 09:05:31

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

Reported by ramosian.glider on 2015-07-30 09:06:55