X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-api-so.c;h=b285d4ad03e8b9d3db79676d9d0fcc63f55ff449;hb=ac7a95223a6314cca6250495ea59c3cf7e46e89e;hp=55e474c627ae8c866793ba2cd6295cdd1158de9a;hpb=8ce4768e7bbb2f7fc00c885591aa20429f4c83af;p=src%2Fapp-framework-binder.git diff --git a/src/afb-api-so.c b/src/afb-api-so.c index 55e474c6..b285d4ad 100644 --- a/src/afb-api-so.c +++ b/src/afb-api-so.c @@ -27,7 +27,37 @@ #include "afb-api-so.h" #include "afb-api-so-v1.h" #include "afb-api-so-v2.h" +#include "afb-api-so-vdyn.h" #include "verbose.h" +#include "sig-monitor.h" + +struct safe_dlopen +{ + const char *path; + void *handle; + int flags; +}; + +static void safe_dlopen_cb(int sig, void *closure) +{ + struct safe_dlopen *sd = closure; + if (!sig) + sd->handle = dlopen(sd->path, sd->flags); + else { + ERROR("dlopen of %s raised signal %s", sd->path, strsignal(sig)); + sd->handle = NULL; + } +} + +static void *safe_dlopen(const char *filename, int flags) +{ + struct safe_dlopen sd; + sd.path = filename; + sd.flags = flags; + sd.handle = NULL; + sig_monitor(0, safe_dlopen_cb, &sd); + return sd.handle; +} static int load_binding(const char *path, int force, struct afb_apiset *apiset) { @@ -36,12 +66,12 @@ static int load_binding(const char *path, int force, struct afb_apiset *apiset) // This is a loadable library let's check if it's a binding rc = -!!force; - handle = dlopen(path, RTLD_NOW | RTLD_LOCAL); + handle = safe_dlopen(path, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); if (handle == NULL) { if (force) ERROR("binding [%s] not loadable: %s", path, dlerror()); else - INFO("binding [%s] not loadable: %s", path, dlerror()); + WARNING("binding [%s] not loadable: %s", path, dlerror()); goto error; } @@ -54,6 +84,15 @@ static int load_binding(const char *path, int force, struct afb_apiset *apiset) if (rc) return 0; /* yes version 2 */ + /* try the version dyn */ + rc = afb_api_so_vdyn_add(path, handle, apiset); + if (rc < 0) { + /* error when loading a valid dyn binding */ + goto error2; + } + if (rc) + return 0; /* yes version dyn */ + /* try the version 1 */ rc = afb_api_so_v1_add(path, handle, apiset); if (rc < 0) { @@ -116,10 +155,52 @@ static int adddirs(char path[PATH_MAX], size_t end, struct afb_apiset *apiset, i if (dent->d_type == DT_DIR) { /* case of directories */ if (dent->d_name[0] == '.') { +/* +Exclude from the search of bindings any +directory starting with a dot (.) by default. + +It is possible to reactivate the prvious behaviour +by defining the following preprocessor variables + + - AFB_API_SO_ACCEPT_DOT_PREFIXED_DIRS + + When this variable is defined, the directories + starting with a dot are searched except + if their name is "." or ".." or ".debug" + + - AFB_API_SO_ACCEPT_DOT_DEBUG_DIRS + + When this variable is defined and the variable + AFB_API_SO_ACCEPT_DOT_PREFIXED_DIRS is also defined + scans any directory not being "." or "..". + +The previous behaviour was like difining the 2 variables, +meaning that only . and .. were excluded from the search. + +This change is intended to definitely solve the issue +SPEC-662. Yocto installed the debugging symbols in the +subdirectory .debug. For example the binding.so also +had a .debug/binding.so file attached. Opening that +debug file made dlopen crashing. +See https://sourceware.org/bugzilla/show_bug.cgi?id=22101 + */ +#if !defined(AFB_API_SO_ACCEPT_DOT_PREFIXED_DIRS) /* not defined by default */ + continue; /* ignore any directory beginnign with a dot */ +#else if (len == 1) - continue; + continue; /* . */ if (dent->d_name[1] == '.' && len == 2) - continue; + continue; /* .. */ +#if !defined(AFB_API_SO_ACCEPT_DOT_DEBUG_DIRS) /* not defined by default */ + if (len == 6 + && dent->d_name[1] == 'd' + && dent->d_name[2] == 'e' + && dent->d_name[3] == 'b' + && dent->d_name[4] == 'u' + && dent->d_name[5] == 'g') + continue; /* .debug */ +#endif +#endif } memcpy(&path[end], dent->d_name, len+1); rc = adddirs(path, end+len, apiset, failstops);