diff options
-rw-r--r-- | lib/interception/interception_linux.cc | 8 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/Inputs/no-interception-dso.c | 3 | ||||
-rw-r--r-- | test/ubsan/TestCases/Misc/no-interception.cpp | 20 | ||||
-rw-r--r-- | test/ubsan/lit.common.cfg | 2 |
4 files changed, 33 insertions, 0 deletions
diff --git a/lib/interception/interception_linux.cc b/lib/interception/interception_linux.cc index 23780429d..5299c42d6 100644 --- a/lib/interception/interception_linux.cc +++ b/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/test/ubsan/TestCases/Misc/Inputs/no-interception-dso.c b/test/ubsan/TestCases/Misc/Inputs/no-interception-dso.c new file mode 100644 index 000000000..5ccc9b63d --- /dev/null +++ b/test/ubsan/TestCases/Misc/Inputs/no-interception-dso.c @@ -0,0 +1,3 @@ +int dso_function(int i) { + return i + 1; +} diff --git a/test/ubsan/TestCases/Misc/no-interception.cpp b/test/ubsan/TestCases/Misc/no-interception.cpp new file mode 100644 index 000000000..c82fed3bf --- /dev/null +++ b/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 <limits.h> + +int dso_function(int); + +int main(int argc, char **argv) { + // CHECK: signed integer overflow + dso_function(INT_MAX); +} diff --git a/test/ubsan/lit.common.cfg b/test/ubsan/lit.common.cfg index f34d5867d..e1bd349af 100644 --- a/test/ubsan/lit.common.cfg +++ b/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'] |