Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CFRelease(kCFAllocatorSystemDefault) fails within __asan_init() #87

Closed
ramosian-glider opened this issue Aug 31, 2015 · 7 comments
Closed

Comments

@ramosian-glider
Copy link
Member

Originally reported on Google Code with ID 87

To reproduce, build Chromium base_unittests with the current ASan on OS X 10.6

$ gdb out/Release/base_unittests
(gdb) r

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00000010
0x91dfa9f9 in objc_selopt::objc_selopt_t::get ()
(gdb) bt
#0  0x91dfa9f9 in objc_selopt::objc_selopt_t::get ()
#1  0x91de73ef in _objc_search_builtins ()
#2  0x91de71ee in __sel_registerName ()
#3  0x95f3df0c in CFRelease ()
#4  0x96013a10 in CFAllocatorSetDefault ()
#5  0x01704b61 in __asan_unregister_globals ()
#6  0x8fe0ed69 in __dyld__ZN16ImageLoaderMachO18doModInitFunctionsERKN11ImageLoader11LinkContextE
()
#7  0x8fe0d31a in __dyld__ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEj
()
#8  0x8fe0d2be in __dyld__ZN11ImageLoader23recursiveInitializationERKNS_11LinkContextEj
()
#9  0x8fe0d3cd in __dyld__ZN11ImageLoader15runInitializersERKNS_11LinkContextE ()
#10 0x8fe024a9 in __dyld__ZN4dyld24initializeMainExecutableEv ()
#11 0x8fe0794e in __dyld__ZN4dyld5_mainEPK12macho_headermiPPKcS5_S5_ ()
#12 0x8fe018b1 in __dyld__ZN13dyldbootstrap5startEPK12macho_headeriPPKcl ()
#13 0x8fe01057 in __dyld__dyld_start ()

(gdb) br _objc_search_builtins
Breakpoint 2 at 0x91de72dc
(gdb) r

Breakpoint 2, 0x91de72dc in _objc_search_builtins ()
(gdb) i r
eax            0x960716b8   -1777920328
ecx            0x1  1
edx            0x1  1
ebx            0x91de72db   -1847692581
esp            0xbfffd350   0xbfffd350
ebp            0xbfffd388   0xbfffd388
esi            0x0  0
edi            0x960716b8   -1777920328
eip            0x91de72dc   0x91de72dc <_objc_search_builtins+15>
eflags         0x286    646
cs             0x1b 27
ss             0x23 35
ds             0x23 35
es             0x23 35
fs             0x0  0
gs             0xf  15

(gdb) x/s $eax
0x960716b8 <__PRETTY_FUNCTION__.28290+422>:  "release"

Reported by ramosian.glider on 2012-07-04 17:05:56

@ramosian-glider
Copy link
Member Author

The problem is reproducible only when Chromium Framework is build with component=shared_library
(opposed to component=static_library)

Looks like in this case __CFAllocatorInitialize isn't called before __asan_init(),
and __kCFAllocatorSystemDefault._context.info isn't initialized, which leads to a NULL
deref.
Because it's hard to call __CFAllocatorInitialize directly, the fix should probably
just initialize __kCFAllocatorSystemDefault._context.info with the return value malloc_zone_default()
before it has been replaced by ASan.

Reported by ramosian.glider on 2012-07-05 10:16:19

@ramosian-glider
Copy link
Member Author

Looks like it's insufficient to re-implement parts of __CFAllocatorInitialize in the
runtime, so I've ended up trying to call some existing initialization routine.

__CFAllocatorInitialize can't be called solely: it's a private symbol, moreover, CF
relies on the fact it's called after
         __kCFNotATypeTypeID = _CFRuntimeRegisterClass(&__CFNotATypeClass);
        __kCFTypeTypeID = _CFRuntimeRegisterClass(&__CFTypeClass);
, which also initialize private symbols (see http://opensource.apple.com/source/CF/CF-550.43/CFRuntime.c)
Thus, one needs to call at least __CFInitialize in order to initialize properly.

Doing so has caused many assertions to fire (__CFInitialize() uses calloc(), malloc(),
strdup(), strchr() etc.) and finally caused error reports about unallocated memory
being passed to free().

My current idea is to intercept __CFInitialize and replace the default CFAllocator
right after the exit from it: until then neither of the CFAllocators can be used reliably,
so this should be safe.

Reported by ramosian.glider on 2012-07-05 13:40:33

@ramosian-glider
Copy link
Member Author

r159749 should fix the issue.

Reported by ramosian.glider on 2012-07-05 14:47:26

  • Status changed: Fixed

@ramosian-glider
Copy link
Member Author

Because __CFRuntimeClassTableSize is unavailable on 10.7, I've landed r159819, which
unconditionally calls CFAllocatorSetDefault() from __asan_init() on Lion.

This means the described bug may (possibly) re-appear on Lion, and in order to prevent
this we'll need to check some bits in __kCFAllocatorSystemDefault.
However I couldn't reproduce the problem with Chromium tests in both component=shared_library
and component=static_library, so this is a minor problem now.

Reported by ramosian.glider on 2012-07-06 12:17:37

  • Status changed: Started
  • Labels added: Priority-Low
  • Labels removed: Priority-Medium

@ramosian-glider
Copy link
Member Author

I've got rid of the __CFRuntimeClassTableSize (checking for kCFAllocatorSystemDefault._base._cfisa
instead), but it turns out that CFAllocatorCreate() depends on __CFInitialize() on
Lion, so it should be moved to the __CFInitialize() wrapper as well.

Reported by ramosian.glider on 2012-07-06 13:08:26

@ramosian-glider
Copy link
Member Author

Ok, now CFAllocatorReplace() is called from __asan_init() or CFInitialize() depending
on which is called later. I've checked that ASan tests pass and Chromium base_unittests
run when built in both modes on both Lion and Snow Leopard.

Reported by ramosian.glider on 2012-07-06 14:14:58

  • Status changed: Fixed

@ramosian-glider
Copy link
Member Author

Adding Project:AddressSanitizer as part of GitHub migration.

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

  • Labels added: ProjectAddressSanitizer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant