On Fri, May 23, 2014 at 09:30:12AM +0400, Yury Gribov wrote:
> > much better would be just dlsym a couple of
> > interesting symbols to verify that libasan.so.1 is ahead
> > of libc.so.6, libstdc++.so.6, libpthread.so.0 (whatever else
> > you want to override).
> 
> One problem with dlsym() that I've seen is that it causes a call to
> malloc on failure (to allocate buffer for dlerror()) which forces
> allocator initialization and breaks Asan's delayed initialization
> feature.
> 
> Also on Linux dlsym() tends to return address of executable's PLT
> entry which is useless.

You don't need to use dlsym actually, just comparing
if (malloc != __hidden_malloc_alias) would do it.
You're right that will return PLT slots in the executable though.

> > Otherwise libasan apps will simply stop
> > working altogether if LD_PRELOAD is set, to whatever library,
> > even if it doesn't define any symbols you care about.
> 
> Right but I'm not sure whether failing fast here is necessarily bad.

I think it is very bad.  In fact, if you really want such a check,
I'd say it shouldn't be at least enabled by default, unless some
env var requests it; and document that if you are having troubles with
asan sanitized programs, try this magic env var to get better
troubleshooting.
Even before this exaggerated check asan imposes far more restrictions than
good, and this just makes asan less usable just for fear that it wouldn't
work right.  Most preloaded libs will just provide symbols asan never cares
about, or even if say they override malloc, it could be just some malloc
wrappers that add some bookkeeping and call the original malloc through
dlsym RTLD_NEXT, or even if you say override malloc completely without
calling the original implementation, the world doesn't end, the shadow
mem of those allocations just won't be surrounded by protected paddings,
so what, you don't detect out of bounds for malloc, but can still detect
out of bounds in your program's stack etc.
Ditto for string ops etc.
What really matters is that to avoid crashes, libasan unfortunately has
to be constructed very early, but this check doesn't help with that,
furthermore this code is run during the libasan construction and thus if it
is not early, the library has already crashed by then.

> Imagine preloaded library has an initializer which calls intercepted
> APIs. Asan didn't get a chance to initialize at the point of call
> and if interceptor doesn't contain a sanity call to asan_init,
> we are risking hard-to-debug runtime error (call to NULL, etc.).
> I've seen numerous bugs like this (both locally and on mailing
> lists) and they were main motivation to add this check.

That is nonsense.  Early in the symbol search scope is the opposite of being
initialized early, on the contrary, such libraries are initialized last.
That is the reason why LD_PRELOAD=libasan.so.1 still doesn't help with
the __asan_init_v3 being performed early, you need either .preinit_array
in the executable, or the ctor called by some library late in the symbol
search scope (== early constructed).

> > Typically people in LD_PRELOAD override malloc (which we want to
> diagnose),
> > or far more rarely stringops (e.g. memstomp, also undesirable).
> 
> I wonder whether overriding Asan's malloc, etc. is expected to work
> at all? Perhaps banning it altogether is just the safest thing to
> do?

Don't know why you want to ban everything.

        Jakub

Reply via email to