From: Peter Collingbourne Date: Fri, 10 Nov 2017 22:09:37 +0000 (+0000) Subject: sanitizer_common: Try looking up symbols with RTLD_DEFAULT if RTLD_NEXT does not... X-Git-Tag: llvmorg-6.0.0-rc1~3659 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0f43b92980b66b19f03779c5a9b701e377b67e08;p=platform%2Fupstream%2Fllvm.git sanitizer_common: Try looking up symbols with RTLD_DEFAULT if RTLD_NEXT does not work. If the lookup using RTLD_NEXT failed, the sanitizer runtime library is later in the library search order than the DSO that we are trying to intercept, which means that we cannot intercept this function. We still want the address of the real definition, though, so look it up using RTLD_DEFAULT. Differential Revision: https://reviews.llvm.org/D39779 llvm-svn: 317930 --- diff --git a/compiler-rt/lib/interception/interception_linux.cc b/compiler-rt/lib/interception/interception_linux.cc index 2378042..5299c42 100644 --- a/compiler-rt/lib/interception/interception_linux.cc +++ b/compiler-rt/lib/interception/interception_linux.cc @@ -29,6 +29,14 @@ bool GetRealFunctionAddress(const char *func_name, uptr *func_addr, if (internal_strcmp(func_name, "sigaction") == 0) func_name = "__sigaction14"; #endif *func_addr = (uptr)dlsym(RTLD_NEXT, func_name); + if (!*func_addr) { + // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is + // later in the library search order than the DSO that we are trying to + // intercept, which means that we cannot intercept this function. We still + // want the address of the real definition, though, so look it up using + // RTLD_DEFAULT. + *func_addr = (uptr)dlsym(RTLD_DEFAULT, func_name); + } return real == wrapper; } diff --git a/compiler-rt/test/ubsan/TestCases/Misc/Inputs/no-interception-dso.c b/compiler-rt/test/ubsan/TestCases/Misc/Inputs/no-interception-dso.c new file mode 100644 index 0000000..5ccc9b6 --- /dev/null +++ b/compiler-rt/test/ubsan/TestCases/Misc/Inputs/no-interception-dso.c @@ -0,0 +1,3 @@ +int dso_function(int i) { + return i + 1; +} diff --git a/compiler-rt/test/ubsan/TestCases/Misc/no-interception.cpp b/compiler-rt/test/ubsan/TestCases/Misc/no-interception.cpp new file mode 100644 index 0000000..c82fed3 --- /dev/null +++ b/compiler-rt/test/ubsan/TestCases/Misc/no-interception.cpp @@ -0,0 +1,20 @@ +// REQUIRES: android + +// Tests that ubsan can detect errors on Android if libc appears before the +// runtime in the library search order, which means that we cannot intercept +// symbols. + +// RUN: %clangxx %p/Inputs/no-interception-dso.c -fsanitize=undefined -fPIC -shared -o %dynamiclib %ld_flags_rpath_so + +// Make sure that libc is first in DT_NEEDED. +// RUN: %clangxx %s -lc -o %t %ld_flags_rpath_exe +// RUN: %run %t 2>&1 | FileCheck %s + +#include + +int dso_function(int); + +int main(int argc, char **argv) { + // CHECK: signed integer overflow + dso_function(INT_MAX); +} diff --git a/compiler-rt/test/ubsan/lit.common.cfg b/compiler-rt/test/ubsan/lit.common.cfg index f34d586..e1bd349 100644 --- a/compiler-rt/test/ubsan/lit.common.cfg +++ b/compiler-rt/test/ubsan/lit.common.cfg @@ -74,3 +74,5 @@ if config.host_os not in ['Linux', 'Darwin', 'FreeBSD', 'Windows', 'NetBSD']: config.unsupported = True config.available_features.add('arch=' + config.target_arch) + +config.excludes = ['Inputs']