X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-api-so.c;h=02e986e72fa086d41db1b185f503157bb545103d;hb=2f38d2ea0537107def8514dc2e0c680ff8d31ca8;hp=2b71d92fd633bf8167f9add393532aa465bc9cb9;hpb=b28c89df26160c56b9a99139c3153953868d36fc;p=src%2Fapp-framework-binder.git diff --git a/src/afb-api-so.c b/src/afb-api-so.c index 2b71d92f..02e986e7 100644 --- a/src/afb-api-so.c +++ b/src/afb-api-so.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016, 2017, 2018 "IoT.bzh" + * Copyright (C) 2015-2020 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -15,9 +15,12 @@ * limitations under the License. */ +#if WITH_DYNAMIC_BINDING + #define _GNU_SOURCE #include +#include #include #include #include @@ -25,17 +28,19 @@ #include #include "afb-api-so.h" -#include "afb-api-so-v2.h" #include "afb-api-so-v3.h" #include "verbose.h" #include "sig-monitor.h" -#if defined(WITH_LEGACY_BINDING_V1) +#if WITH_LEGACY_BINDING_V1 # include "afb-api-so-v1.h" #endif -#if defined(WITH_LEGACY_BINDING_VDYN) +#if WITH_LEGACY_BINDING_VDYN # include "afb-api-so-vdyn.h" #endif +#if WITH_LEGACY_BINDING_V2 +# include "afb-api-so-v2.h" +#endif struct safe_dlopen { @@ -70,10 +75,23 @@ static int load_binding(const char *path, int force, struct afb_apiset *declare_ int obsolete = 0; int rc; void *handle; + static int dlopen_flags = 0; + + /* compute the dlopen flags */ + if (dlopen_flags == 0) { + /* For ASan mode, export AFB_NO_RTLD_DEEPBIND=1, to disable RTLD_DEEPBIND */ + char *string = secure_getenv("AFB_NO_RTLD_DEEPBIND"); + if (string && string[0] == '1' && string[1] == 0) + dlopen_flags = RTLD_NOW | RTLD_LOCAL; + else + dlopen_flags = RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND; + } - // This is a loadable library let's check if it's a binding + /* set default return code rc according to force */ rc = -!!force; - handle = safe_dlopen(path, RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND); + + /* try to open the library */ + handle = safe_dlopen(path, dlopen_flags); if (handle == NULL) { if (force) ERROR("binding [%s] not loadable: %s", path, dlerror()); @@ -81,6 +99,9 @@ static int load_binding(const char *path, int force, struct afb_apiset *declare_ WARNING("binding [%s] not loadable: %s", path, dlerror()); goto error; } + /* + * This is a loadable library let's check if it's a binding ... + */ /* try the version 3 */ rc = afb_api_so_v3_add(path, handle, declare_set, call_set); @@ -91,6 +112,7 @@ static int load_binding(const char *path, int force, struct afb_apiset *declare_ if (rc) return 0; /* yes version 3 */ +#if WITH_LEGACY_BINDING_V2 /* try the version 2 */ rc = afb_api_so_v2_add(path, handle, declare_set, call_set); if (rc < 0) { @@ -99,8 +121,14 @@ static int load_binding(const char *path, int force, struct afb_apiset *declare_ } if (rc) return 0; /* yes version 2 */ +#else + if (dlsym(handle, "afbBindingV2")) { + WARNING("binding [%s]: version 2 not supported", path); + obsolete = 1; + } +#endif -#if defined(WITH_LEGACY_BINDING_VDYN) +#if WITH_LEGACY_BINDING_VDYN /* try the version dyn */ rc = afb_api_so_vdyn_add(path, handle, declare_set, call_set); if (rc < 0) { @@ -116,7 +144,7 @@ static int load_binding(const char *path, int force, struct afb_apiset *declare_ } #endif -#if defined(WITH_LEGACY_BINDING_V1) +#if WITH_LEGACY_BINDING_V1 /* try the version 1 */ rc = afb_api_so_v1_add(path, handle, declare_set, call_set); if (rc < 0) { @@ -152,6 +180,7 @@ static int adddirs(char path[PATH_MAX], size_t end, struct afb_apiset *declare_s { DIR *dir; struct dirent *dent; + struct stat st; size_t len; int rc = 0; @@ -175,12 +204,19 @@ static int adddirs(char path[PATH_MAX], size_t end, struct afb_apiset *declare_s break; } + /* get the name and inspect dereferenced link instead of the directory entry */ len = strlen(dent->d_name); if (len + end >= PATH_MAX) { - ERROR("path too long while scanning bindings for %s", dent->d_name); + ERROR("path too long while scanning bindings for %.*s%s", (int)end, path, dent->d_name); continue; } - if (dent->d_type == DT_DIR) { + memcpy(&path[end], dent->d_name, len+1); + rc = stat(path, &st); + if (rc < 0) { + ERROR("getting status of %s failed: %m", path); + continue; + } + else if (S_ISDIR(st.st_mode)) { /* case of directories */ if (dent->d_name[0] == '.') { /* @@ -213,7 +249,7 @@ 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 */ + continue; /* ignore any directory beginning with a dot */ #else if (len == 1) continue; /* . */ @@ -230,13 +266,11 @@ See https://sourceware.org/bugzilla/show_bug.cgi?id=22101 #endif #endif } - memcpy(&path[end], dent->d_name, len+1); rc = adddirs(path, end+len, declare_set, call_set, failstops); - } else if (dent->d_type == DT_REG || dent->d_type == DT_LNK) { + } else if (S_ISREG(st.st_mode)) { /* case of files */ if (memcmp(&dent->d_name[len - 3], ".so", 4)) continue; - memcpy(&path[end], dent->d_name, len+1); rc = load_binding(path, 0, declare_set, call_set); } if (rc < 0 && failstops) { @@ -307,3 +341,4 @@ int afb_api_so_add_pathset_nofails(const char *pathset, struct afb_apiset *decla return afb_api_so_add_pathset(pathset, declare_set, call_set, 0); } +#endif