From patchwork Tue Apr 21 09:00:20 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?=C5=81ukasz_Stelmach?= X-Patchwork-Id: 133451 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from vm01.sourceware.org (localhost [127.0.0.1]) by sourceware.org (Postfix) with ESMTP id 5BF564BA23C0 for ; Tue, 21 Apr 2026 09:01:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5BF564BA23C0 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=samsung.com header.i=@samsung.com header.a=rsa-sha256 header.s=mail20170921 header.b=EzwERCXN X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mailout2.w1.samsung.com (mailout2.w1.samsung.com [210.118.77.12]) by sourceware.org (Postfix) with ESMTPS id 056D34BA23D8 for ; Tue, 21 Apr 2026 09:00:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 056D34BA23D8 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=samsung.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=samsung.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 056D34BA23D8 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=210.118.77.12 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776762044; cv=none; b=h0biTJCQHZ7zykA162lMdolSJSN1Q51C1QWdJ2401k92TFPTOOk/pQ5+Lml2GBh/fp2wyGQfAGi7R5jmDekpmpL8po28GcoIXM7CdgF+j3DtHA233wV91KonJ0USXcsah9XjIoIiuSG2lSoPZQlCyuyYDP0Ew9yddtByRV1Knj4= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1776762044; c=relaxed/simple; bh=bNXKFRfCYF4nDqscBfl/HkCjlISV9FKlGJcdM7KIkpY=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=rEvAqCWycZUmfPvD7yXhb12XE5S20qrISwmLfdzhDIrDpZ69uMAqD2wSUOK4VbTuoZVLRYPdTIUg020wETzI03SaphUmi7jla7sy5OzwvBrdB/0Cz9Hmz09p7V6+COGp66DTEOC/XmNxFttMmE7+tuKgT5qGyg/c2+lXdYOdBmk= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 056D34BA23D8 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20260421090042euoutp023b6868a01f6f86ee3bd2428714aba2eb~oU6oFkO9y3042630426euoutp02d for ; Tue, 21 Apr 2026 09:00:42 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20260421090042euoutp023b6868a01f6f86ee3bd2428714aba2eb~oU6oFkO9y3042630426euoutp02d DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1776762042; bh=moJKZrOGffDYINQNHpLAacdtmcRO0GpSXIShBRZbkIc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=EzwERCXNsr0EpSGGElTN+cyai8g5l3o+KHkg4apNgN1sSPu5zM87Lc06ZDgosv7lQ YUZKDtZtx8ukYUfJiR9G3Yw+r84kQNfUMh9MeEb+hBNdcLCxywf5ZSotCEYe61w1P7 VQwIBQAqBFrQ5xpWWeewQEbNuwnxixv+Y7c3pJME= Received: from eusmtip1.samsung.com (unknown [203.254.199.221]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20260421090042eucas1p2e4ebb18985d22491b667ec0eed9bcffd~oU6nxqrSy0935309353eucas1p2S; Tue, 21 Apr 2026 09:00:42 +0000 (GMT) Received: from localhost (unknown [106.120.51.111]) by eusmtip1.samsung.com (KnoxPortal) with ESMTPA id 20260421090042eusmtip15d6a36d711eed7b35e0e06682e998f6f~oU6nssy0J0168301683eusmtip14; Tue, 21 Apr 2026 09:00:42 +0000 (GMT) From: =?utf-8?q?=C5=81ukasz_Stelmach?= To: libc-alpha@sourceware.org Cc: j.kryszyn@samsung.com, m.szyprowski@samsung.com, k.lewandowsk@samsung.com, cw00.choi@samsung.com, dongkyun.s@samsung.com, sungguk.na@samsung.com, Mateusz Moscicki , =?utf-8?q?=C5=81ukasz_Stelmach?= Subject: [RFC 3/3] Add a solution to prevent conflict between symbols loaded from dependencies Date: Tue, 21 Apr 2026 11:00:20 +0200 Message-ID: <20260421090020.59726-4-l.stelmach@samsung.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260421090020.59726-1-l.stelmach@samsung.com> MIME-Version: 1.0 Organization: Samsung R&D Institute Poland X-CMS-MailID: 20260421090042eucas1p2e4ebb18985d22491b667ec0eed9bcffd X-Msg-Generator: CA X-RootMTR: 20260421090042eucas1p2e4ebb18985d22491b667ec0eed9bcffd X-EPHeader: CA X-CMS-RootMailID: 20260421090042eucas1p2e4ebb18985d22491b667ec0eed9bcffd References: <20260421090020.59726-1-l.stelmach@samsung.com> X-Spam-Status: No, score=-10.5 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_PASS, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces~patchwork=sourceware.org@sourceware.org From: Mateusz Moscicki Each section in the dlconf configuration file such as: [some1] path=/usr/lib/some1/ cache=/etc/ld-some1.so.cache [some2] path=/usr/lib/some2/ cache=/etc/ld-some2.so.cache gets its own unique number. During linking, each object (struct link_map) is assigned the number of the section it comes from. Additionally, it also has a list of objects it is directly linked with (those in its DT_NEEDED list). Based on these data, during the symbol resolution process, it is checked whether a given object can use a symbol from another object. The goal is to allow objects to use symbols from objects in the same section or from other sections if it is a direct dependency (DT_NEEDED). This makes it possible for a library from /usr/lib/some1/ to use its own version of, for example, libpng.so, while it loads another dependency from /usr/lib/ that requires /usr/lib/libpng.so. Signed-off-by: Mateusz Mościcki Signed-off-by: Łukasz Stelmach --- elf/dl-call-libc-early-init.c | 3 ++ elf/dl-close.c | 9 ++++ elf/dl-deps.c | 21 +++++++++ elf/dl-load.c | 30 +++++++++++- elf/dl-lookup.c | 24 ++++++++++ elf/dl-object.c | 5 ++ elf/dl-open.c | 1 + elf/dlconf-print.c | 3 ++ elf/dlconf.c | 86 +++++++++++++++++++++++++++++++++-- elf/dlconf.h | 11 ++++- elf/rtld.c | 10 ++++ include/link.h | 18 ++++++++ 12 files changed, 212 insertions(+), 9 deletions(-) diff --git a/elf/dl-call-libc-early-init.c b/elf/dl-call-libc-early-init.c index 38b7ec0a42..c2cc0391a2 100644 --- a/elf/dl-call-libc-early-init.c +++ b/elf/dl-call-libc-early-init.c @@ -28,6 +28,9 @@ _dl_call_libc_early_init (struct link_map *libc_map, _Bool initial) /* There is nothing to do if we did not actually load libc.so. */ if (libc_map == NULL) return; +#ifdef DLCONF + libc_map->l_crossvisible = true; +#endif /* DLCONF */ const ElfW(Sym) *sym = _dl_lookup_direct (libc_map, "__libc_early_init", diff --git a/elf/dl-close.c b/elf/dl-close.c index 88226245eb..a63f533570 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -662,6 +662,15 @@ _dl_close_worker (struct link_map *map, bool force) free ((char *) imap->l_origin); free (imap->l_reldeps); +#ifdef DLCONF + struct dep_list *depele = imap->l_crossdep; + while (depele) + { + struct dep_list *depele_next = depele->next; + free(depele); + depele = depele_next; + } +#endif /* Print debugging message. */ if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES)) diff --git a/elf/dl-deps.c b/elf/dl-deps.c index eb1d3416a9..568933fd0b 100644 --- a/elf/dl-deps.c +++ b/elf/dl-deps.c @@ -153,6 +153,11 @@ _dl_map_object_deps (struct link_map *map, /* No loaded object so far. */ nlist = 0; +#ifdef DLCONF + if (map->l_type == lt_executable) + map->l_crossvisible = true; +#endif + /* First load MAP itself. */ preload (known, &nlist, map); @@ -240,6 +245,22 @@ _dl_map_object_deps (struct link_map *map, } else dep = args.aux; +#ifdef DLCONF + if (dep->l_crossns != runp->map->l_crossns) + { + struct dep_list *depele + = malloc (sizeof (struct dep_list)); + if (depele == NULL) + { + _dl_signal_error ( + ENOMEM, map->l_name, NULL, + N_ ("cannot allocate cross dependency list")); + } + depele->map = dep; + depele->next = runp->map->l_crossdep; + runp->map->l_crossdep = depele; + } +#endif /* DLCONF */ if (! dep->l_reserved) { diff --git a/elf/dl-load.c b/elf/dl-load.c index 997e1f0d1d..6acdf615e8 100644 --- a/elf/dl-load.c +++ b/elf/dl-load.c @@ -1917,6 +1917,7 @@ _dl_map_object (struct link_map *loader, const char *name, assert (nsid < GL(dl_nns)); #ifdef DLCONF + size_t crossns = 0; bool try_default = true; char full_path_buff[PATH_MAX]; const char *full_path = NULL; @@ -1939,7 +1940,8 @@ _dl_map_object (struct link_map *loader, const char *name, } } - char *cached = dlconf_get_cached_path (full_path, name, &try_default); + char *cached = dlconf_get_cached_path(full_path, name, &crossns, &try_default); + bool name_is_libc = strcmp (name, LIBC_SO) == 0 || strcmp (name, LD_SO) == 0; #endif /* DLCONF */ @@ -1951,6 +1953,25 @@ _dl_map_object (struct link_map *loader, const char *name, yet been opened. */ if (__glibc_unlikely ((l->l_faked | l->l_removed) != 0)) continue; + +#ifdef DLCONF + if (cached != NULL) + { + /* ld.so and libc.so can always by found regardless of the section in + * which they are located. So crossns check is performed for all + * other libraries */ + if (!name_is_libc) + { + if (l->l_crossns != crossns) + continue; + + /* Here we compare the full path of the library */ + if (strcmp (cached, l->l_name) != 0) + continue; + } + } +#endif /* DLCONF */ + if (!_dl_name_match_p (name, l)) { const char *soname; @@ -2232,8 +2253,13 @@ _dl_map_object (struct link_map *loader, const char *name, } void *stack_end = __libc_stack_end; - return _dl_map_object_from_fd (name, origname, fd, &fb, realname, loader, + l = _dl_map_object_from_fd (name, origname, fd, &fb, realname, loader, type, mode, &stack_end, nsid); +#ifdef DLCONF + if (l != NULL) + l->l_crossns = dlconf_get_section_id(l->l_name); +#endif + return l; } struct add_path_state diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c index 19ad2a25c5..9f29861559 100644 --- a/elf/dl-lookup.c +++ b/elf/dl-lookup.c @@ -31,6 +31,9 @@ #include #include +#ifdef DLCONF +#include +#endif #include #define VERSTAG(tag) (DT_NUM + DT_THISPROCNUM + DT_VERSIONTAGIDX (tag)) @@ -357,6 +360,27 @@ do_lookup_x (const char *undef_name, unsigned int new_hash, { const struct link_map *map = list[i]->l_real; +#ifdef DLCONF + if (undef_map != NULL && !map->l_crossvisible + && map->l_crossns != undef_map->l_crossns) + { + bool found = false; + struct dep_list *dep = NULL; + + for (dep = undef_map->l_crossdep; dep; dep = dep->next) + { + if (dep->map == map) + { + found = true; + break; + } + } + + if (!found) + continue; + } +#endif /* DLCONF */ + /* Here come the extra test needed for `_dl_lookup_symbol_skip'. */ if (map == skip) continue; diff --git a/elf/dl-object.c b/elf/dl-object.c index 931ad308e6..f8199db2fc 100644 --- a/elf/dl-object.c +++ b/elf/dl-object.c @@ -98,6 +98,11 @@ _dl_new_object (char *realname, const char *libname, int type, new->l_real = new; new->l_symbolic_searchlist.r_list = (struct link_map **) ((char *) (new + 1) + audit_space); +#ifdef DLCONF + new->l_crossns = 0; + new->l_crossdep = NULL; + new->l_crossvisible = false; +#endif new->l_libname = newname = (struct libname_list *) (new->l_symbolic_searchlist.r_list + 1); diff --git a/elf/dl-open.c b/elf/dl-open.c index 70d190a246..d323ca93fa 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -588,6 +588,7 @@ dl_open_worker_begin (void *a) { _dl_signal_error (EINVAL, file, NULL, N_ ("prohibited loading path")); } + new->l_crossns = dlconf_get_section_id(new->l_name); #endif /* DLCONF */ /* If the pointer returned is NULL this means the RTLD_NOLOAD flag is diff --git a/elf/dlconf-print.c b/elf/dlconf-print.c index ba009e8ef6..c4e8425203 100644 --- a/elf/dlconf-print.c +++ b/elf/dlconf-print.c @@ -176,6 +176,7 @@ static int _print_conf_dat_tree (const struct conf_dat_entry_with_children *tree _dl_printf("%s%s%s%s\n", prefix, conn, tree->children[i]->name, addon); _dl_printf("%s%s%sisolation: %d\n", prefix, conn2, conn3, tree->children[i]->conf_dat_entry->isolation); _dl_printf("%s%s%sdlopen_isolation: %d\n", prefix, conn2, conn3, tree->children[i]->conf_dat_entry->dlopen_isolation); + _dl_printf("%s%s%ssection_id: %d\n", prefix, conn2, conn3, tree->children[i]->conf_dat_entry->section_id); list = tree->children[i]->conf_dat_entry->caches; _print_list(list, "caches", prefix, conn2, conn3); @@ -193,6 +194,7 @@ static int print_conf_dat_tree (const struct conf_dat_entry_with_children *centr _dl_printf("/\n"); _dl_printf("| isolation: %d\n", centry->conf_dat_entry->isolation); _dl_printf("| dlopen_isolation: %d\n", centry->conf_dat_entry->dlopen_isolation); + _dl_printf("| section_id: %d\n", centry->conf_dat_entry->section_id); _print_list(centry->conf_dat_entry->caches, "caches", "| ", "", ""); _print_list(centry->conf_dat_entry->dlopen_paths, "dlopen_paths", "| ", "", ""); @@ -263,3 +265,4 @@ exit: close(fd); } + diff --git a/elf/dlconf.c b/elf/dlconf.c index c02d1ec1be..765ad6203b 100644 --- a/elf/dlconf.c +++ b/elf/dlconf.c @@ -15,6 +15,7 @@ You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, see . */ +#include "ldsodefs.h" #include #include #include @@ -52,6 +53,7 @@ struct cache_info { struct string_list *caches; bool isolation; bool dlopen_isolation; + int32_t section_id; struct cache_info *next; }; @@ -64,6 +66,7 @@ struct node { int32_t caches_idx; int32_t isolation; int32_t dlopen_isolation; + int32_t section_id; struct node **children; int32_t children_count; }; @@ -123,6 +126,7 @@ struct section { struct section_string_list *paths; struct section_string_list *caches; struct section_string_list *dlopen_paths; + int32_t id; bool isolation; bool dlopen_isolation; bool processing; /* Field for cycle detection */ @@ -365,6 +369,7 @@ static void print_cinfo (struct cache_info *cinfo) _dl_debug_printf(" isolation: %d\n", cinfo->isolation); _dl_debug_printf(" dlopen_isolation: %d\n", cinfo->dlopen_isolation); + _dl_debug_printf(" section_id: %d\n", cinfo->section_id); cinfo = cinfo->next; } @@ -1138,14 +1143,18 @@ static int add_new_cinfo(struct cache_info **cinfo, struct section_string_list *caches, struct section_string_list *dlopen_paths, bool isolation, - bool dlopen_isolation) + bool dlopen_isolation, + int32_t *section_id) { struct section_string_list *l; const struct section_string_list *cur_path = paths; - if (cinfo == NULL) + if (cinfo == NULL || section_id == NULL) return DLCONF_ERR_INVAL; + if (cur_path != NULL) + (*section_id)++; + /* If more paths than one were defined in the section, we need to create more objects because one cache_info object can store only one path (for later optimizations). */ @@ -1179,6 +1188,7 @@ static int add_new_cinfo(struct cache_info **cinfo, cinfo_new->dlopen_paths = dlopen_paths_new; cinfo_new->isolation = isolation; cinfo_new->dlopen_isolation = dlopen_isolation; + cinfo_new->section_id = *section_id; cinfo_new->next = NULL; if (*cinfo == NULL) @@ -1231,6 +1241,7 @@ static int add_new_cinfo(struct cache_info **cinfo, static int convert_sections_to_cache_info(struct sections *sections, struct cache_info **cache_info) { int result = DLCONF_ERR_OK; + int32_t section_id = -1; for (size_t i = 0; i < sections->count; i++) { struct section *section = sections->sections[i]; @@ -1242,10 +1253,12 @@ static int convert_sections_to_cache_info(struct sections *sections, struct cach section->caches, section->dlopen_paths, section->isolation, - section->dlopen_isolation)) != DLCONF_ERR_OK) + section->dlopen_isolation, + §ion_id)) != DLCONF_ERR_OK) { goto exit; } + section->id = section_id; } exit: if (result != DLCONF_ERR_OK) @@ -1397,6 +1410,7 @@ static int parse_paraini (const char *content, size_t content_len, struct sectio key_len--; key_len++; + if (key_len == 0) continue; @@ -1724,6 +1738,7 @@ static int insert_to_trie (struct node *base_node, char *token, const struct cac new_child->dlopen_isolation = base_node->dlopen_isolation; new_child->caches_idx = base_node->caches_idx; new_child->dlopen_paths_idx = base_node->dlopen_paths_idx; + new_child->section_id = base_node->section_id; if ((result = insert_to_trie(new_child, new_token, cinfo, saveptr)) != DLCONF_ERR_OK) { @@ -1744,6 +1759,7 @@ static int insert_to_trie (struct node *base_node, char *token, const struct cac new_child->isolation = cinfo->isolation; new_child->dlopen_isolation = cinfo->dlopen_isolation; + new_child->section_id = cinfo->section_id; } exit: @@ -1789,6 +1805,7 @@ static struct node *convert_to_trie (const struct cache_info *cinfo) base_node->isolation = 0; base_node->dlopen_isolation = 0; base_node->dlopen_paths_idx = -1; + base_node->section_id = -1; base_node->caches_idx = -1; while (cinfo != NULL) @@ -1809,6 +1826,7 @@ static struct node *convert_to_trie (const struct cache_info *cinfo) } base_node->isolation = cinfo->isolation; base_node->dlopen_isolation = cinfo->dlopen_isolation; + base_node->section_id = cinfo->section_id; } else { @@ -1987,6 +2005,7 @@ static int _save_trie (const struct node *node, int fd, int32_t *name_offset, in write_or_return(fd, &node->isolation, sizeof(node->isolation)); write_or_return(fd, &node->dlopen_isolation, sizeof(node->dlopen_isolation)); + write_or_return(fd, &node->section_id, sizeof(node->section_id)); *name_offset += strlen(node->name)+1; @@ -2174,7 +2193,7 @@ int load_conf_dat (const char *path) return 0; } -static struct conf_dat_entry *dlconf_find_proper_conf_dat_entry (const char *path) +struct conf_dat_entry *dlconf_find_proper_conf_dat_entry (const char *path) { if (__glibc_unlikely(conf_data == NULL)) { @@ -2246,6 +2265,7 @@ struct conf_dat_entry *dlconf_read_one_conf_dat_entry (void *file, int start) node->isolation = rnode->isolation; node->dlopen_isolation = rnode->dlopen_isolation; + node->section_id = rnode->section_id; node->dlopen_paths = NULL; node->caches = NULL; @@ -2347,7 +2367,48 @@ bool dlconf_allowed_dlopen (const char *file, const void *caller_dlopen) return false; } -char *dlconf_get_cached_path(const char *name, const char *libname, bool *try_default) +size_t dlconf_get_section_id(const char *name) +{ + size_t result; + struct conf_dat_entry *centry; + + if (name == NULL) + return 0; + + centry = dlconf_find_proper_conf_dat_entry(name); + + if (centry == NULL) + return 0; + + result = centry->section_id; + dlconf_free_string_list(centry->caches, false); + dlconf_free_string_list(centry->dlopen_paths, false); + free(centry); + return result; +} + +bool dlconf_have_access(const char *name, const char *libname) +{ + struct conf_dat_entry *centry = dlconf_find_proper_conf_dat_entry(name); + bool result = false; + + if (centry) + { + char *cached = dlconf_find_cached_path (libname, centry->caches); + if (cached) + { + result = true; + free (cached); + } + + dlconf_free_string_list (centry->caches, false); + dlconf_free_string_list (centry->dlopen_paths, false); + free (centry); + } + return result; +} + +char *dlconf_get_cached_path(const char *name, const char *libname, size_t *crossns, bool *try_default) { struct conf_dat_entry *centry; char *cached; @@ -2374,6 +2435,20 @@ char *dlconf_get_cached_path(const char *name, const char *libname, bool *try_de cached = dlconf_find_cached_path(libname, centry->caches); + if (cached != NULL) + { + struct conf_dat_entry *libcentry = dlconf_find_proper_conf_dat_entry (cached); + + if (libcentry) + { + if (crossns != NULL) + *crossns = libcentry->section_id; + + dlconf_free_string_list (libcentry->caches, false); + dlconf_free_string_list (libcentry->dlopen_paths, false); + free (libcentry); + } + } if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_LIBS)) { if (cached != NULL) @@ -2439,3 +2514,4 @@ int dlconf_generate_conf_dat (void) return result; } + diff --git a/elf/dlconf.h b/elf/dlconf.h index 00f408a839..31b537dd6e 100644 --- a/elf/dlconf.h +++ b/elf/dlconf.h @@ -69,6 +69,7 @@ struct conf_dat_raw_entry { int32_t dlopen_paths_offset; int32_t isolation; int32_t dlopen_isolation; + int32_t section_id; }; /* @@ -85,6 +86,7 @@ struct string_list { struct conf_dat_entry { bool isolation; bool dlopen_isolation; + int32_t section_id; struct string_list *caches; struct string_list *dlopen_paths; @@ -110,7 +112,8 @@ struct conf_dat_entry { #define DLCONF_DLPATHS_START_OFFSET offsetof(struct conf_dat_raw_entry, dlopen_paths_offset) #define DLCONF_ISO_OFFSET offsetof(struct conf_dat_raw_entry, isolation) #define DLCONF_DLOPEN_ISO_OFFSET offsetof(struct conf_dat_raw_entry, dlopen_isolation) -#define DLCONF_NODE_FIELDS_COUNT 7 +#define DLCONF_SECTION_ID_OFFSET offsetof(struct conf_dat_raw_entry, section_id) +#define DLCONF_NODE_FIELDS_COUNT 8 #define DLCONF_NODE_SIZE_IN_BYTES DLCONF_NODE_FIELDS_COUNT*sizeof(int32_t) /* @@ -155,7 +158,7 @@ extern bool dlconf_allowed_dlopen (const char *file, const void *caller_dlopen) * name argument is a program name with a path, for which the library is loading. * try_default will be set to true or false depending on whether isolation is true or false. */ -extern char *dlconf_get_cached_path(const char *name, const char *libname, bool *try_default) attribute_hidden; +extern char *dlconf_get_cached_path(const char *name, const char *libname, size_t *crossns, bool *try_default) attribute_hidden; /* * Generate ldconfig.dat from /etc/ldconfig.conf and /etc/ldconfig.conf.d/* files @@ -172,4 +175,8 @@ extern void dlconf_print_conf_dat (void) attribute_hidden; */ char *dlconf_get_executable_path (char *buff, size_t bufflen) attribute_hidden; +struct conf_dat_entry *dlconf_find_proper_conf_dat_entry (const char *path); + +size_t dlconf_get_section_id(const char *name); +bool dlconf_have_access(const char *name, const char *libname); #endif /* _DLCONF_H */ diff --git a/elf/rtld.c b/elf/rtld.c index f70bc7e18c..bc133667be 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -1374,6 +1374,9 @@ dl_main (const ElfW(Phdr) *phdr, _dl_starting_up = 1; #endif +#ifdef DLCONF + GL(dl_rtld_map).l_crossvisible = true; +#endif /* DLCONF */ const char *ld_so_name = _dl_argv[0]; if (*user_entry == (ElfW(Addr)) ENTRY_POINT) { @@ -1670,6 +1673,13 @@ dl_main (const ElfW(Phdr) *phdr, This will be what dlopen on "" returns. */ main_map = _dl_new_object ((char *) "", "", lt_executable, NULL, __RTLD_OPENEXEC, LM_ID_BASE); +#ifdef DLCONF + char full_path_buff[PATH_MAX]; + const char *full_path = NULL; + full_path = dlconf_get_executable_path(full_path_buff, sizeof(full_path_buff)); + main_map->l_crossns = dlconf_get_section_id(full_path); +#endif /* DLCONF */ + assert (main_map != NULL); main_map->l_phdr = phdr; main_map->l_phnum = phnum; diff --git a/include/link.h b/include/link.h index cb0d7d8e2f..a3da3fe146 100644 --- a/include/link.h +++ b/include/link.h @@ -71,6 +71,17 @@ struct r_scope_elem unsigned int r_nlist; }; +#ifdef DLCONF +struct dep_list { + struct link_map *map; + struct dep_list *next; +}; + +struct ns_list { + size_t ns; + struct ns_list *next; +}; +#endif // DLCONF /* Structure to record search path and allocation mechanism. */ struct r_search_path_struct @@ -114,6 +125,13 @@ struct link_map /* Number of the namespace this link map belongs to. */ Lmid_t l_ns; +#ifdef DLCONF + size_t l_crossns; /* Identifier of cross-namespace */ + struct dep_list *l_crossdep; /* List of direct dependencies */ + bool l_crossvisible; /* Flag indication whether a given object is visible + from all cross-namespaces */ +#endif /* DLCONF */ + struct libname_list *l_libname; /* Indexed pointers to dynamic section. [0,DT_NUM) are indexed by the processor-independent tags.