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