tech-userlevel archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Basesystem programs redefine routine symbols from libc



On Sat, Dec 09, 2017 at 03:46:42PM +0100, Kamil Rytarowski wrote:
> I'm testing LLVM sanitizers. Right now, not every one is compatible
> as-is, because there are linker issues. The sanitizers redefine symbols
> for routines in libc like uname(3) in order to sanitize it with internal
> logic. However there exist programs in the basesystem that shadow libc
> symbol routines as well, for example ps(1):
> 
> bin/ps/extern.h:void    uname(struct pinfo *, VARENT *, enum mode);
> bin/ps/keyword.c:      VAR4("user", "USER", LJUST, uname),
> bin/ps/print.c:uname(struct pinfo *pi, VARENT *ve, enum mode mode)

What if, instead of redefining uname() with a different calling
convention than libc's, the program had redefined malloc(3) for some
debugging purpose?  Would that also break the sanitizer's function
interposition?  Seems like linking would produce a duplicate symbol
error.

BTW, here is a fragment of LLVM tsan function interposition, albeit from
a few years ago:

#elif defined(__FreeBSD__)
# define WRAP(x) __interceptor_ ## x
# define WRAPPER_NAME(x) "__interceptor_" #x
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
// FreeBSD's dynamic linker (incompliantly) gives non-weak symbols higher
// priority than weak ones so weak aliases won't work for indirect calls
// in position-independent (-fPIC / -fPIE) mode.
# define DECLARE_WRAPPER(ret_type, func, ...) \
     extern "C" ret_type func(__VA_ARGS__) \
     __attribute__((alias("__interceptor_" #func), visibility("default")));
#else
# define WRAP(x) __interceptor_ ## x
# define WRAPPER_NAME(x) "__interceptor_" #x
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
# define DECLARE_WRAPPER(ret_type, func, ...) \
    extern "C" ret_type func(__VA_ARGS__) \
    __attribute__((weak, alias("__interceptor_" #func), visibility("default")));
#endif

DECLARE_WRAPPER(int, pthread_create, ...), for example, produces an
alias `pthread_create` for `__interceptor_pthread_create`, which calls
the tsan instrumentation and forwards its arguments to libpthread's
`pthread_create`.  The #else case is used on Linux---presumably,
the FreeBSD case is used by NetBSD.  Anyway, in Linux, the `weak`
attribute on the alias seems to allow for a program to provide its own
pthread_create override without a duplicate symbol error.  It makes
sense that in FreeBSD (NetBSD, too?) it would be impossible.

Dave

-- 
David Young
dyoung%pobox.com@localhost    Urbana, IL    (217) 721-9981


Home | Main Index | Thread Index | Old Index