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