Bug 1449604
| Summary: | CC 6.3 libasan.so intercepts dlopen but does not taken the search path from the original module into account | ||
|---|---|---|---|
| Product: | Red Hat Developer Toolset | Reporter: | Piyush Bhoot <pbhoot> |
| Component: | gcc | Assignee: | Marek Polacek <mpolacek> |
| Status: | CLOSED UPSTREAM | QA Contact: | Martin Cermak <mcermak> |
| Severity: | unspecified | Docs Contact: | |
| Priority: | unspecified | ||
| Version: | DTS 6.0 RHEL 7 | CC: | codonell, fweimer, jakub, kanderso, law, mcermak, mnewsome |
| Target Milestone: | alpha | ||
| Target Release: | 6.1 | ||
| Hardware: | Unspecified | ||
| OS: | Unspecified | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2020-06-24 15:09:23 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
I think the libasan dlopen interceptor could be turned into a tail call, which would address the issue.
#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
if (flags()->strict_init_order) { \
StopInitOrderChecking(); \
}
The above probably could just as well happen before the dlopen call.
(In reply to Florian Weimer from comment #4) > I think the libasan dlopen interceptor could be turned into a tail call, > which would address the issue. > > #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) > \ > if (flags()->strict_init_order) { > \ > StopInitOrderChecking(); > \ > } > > The above probably could just as well happen before the dlopen call. I don't see how. The interceptor does some work before the dlopen call and other work after it: INTERCEPTOR(void*, dlopen, const char *filename, int flag) { void *ctx; COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag); if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0); COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag); void *res = REAL(dlopen)(filename, flag); Symbolizer::GetOrInit()->InvalidateModuleList(); COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res); return res; } |
Description of problem: Using gcc6.3 libasan may - under certain circumstances - cause dlopen fail to find the .so library when only the name of the library is used in the call to dlopen (not the relative path). Version-Release number of selected component (if applicable): devtoolset-6-gcc-6.3.1-3.1.el7.x86_64 devtoolset-6-libasan-devel-6.3.1-3.1.el7.x86_64 How reproducible: Alaways Steps to Reproduce: 1. #include <dlfcn.h> #include <iostream> int main() { void *handle = dlopen("libb.so", RTLD_NOW); if (handle == NULL) { std::cout << "Failed to load libb.so" << std::endl; } } #mkdir lib #g++ --sanitize=address -Wl,-rpath='$ORIGIN/lib' -Wl,--enable-new-dtags -ldl -o main main.cpp #cd lib; Create libb.so: int foo() { return 1; } g++ -fPIC -shared b.C -o libb.so Actual results: strace ./main 2>&1 | grep libb.so open("/opt/rh/devtoolset-6/root/usr/lib/../lib64/tls/libb.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) : <snipped> : open("/usr/lib64/libb.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) write(1, "Failed to load libb.so\n", 23Failed to load libb.so Expected results: strace ./main 2>&1 | grep libb.so open("/opt/rh/devtoolset-6/root/usr/lib64/tls/libb.so", O_RDONLY) = -1 ENOENT (No such file or directory) open("/root/cc/lib/libb.so", O_RDONLY) = 3 Additional info: Libasan intercepts dlopen call and the libasan's RUNPATH is taken into account, not the binary one. Running it through strace, it failed to load libb.so