From: "Ludovic Courtès" <ludo@gnu.org>
To: 43491@debbugs.gnu.org
Subject: bug#43491: Fakechroot execution engine can fail to find libraries
Date: Thu, 24 Sep 2020 11:49:07 +0200 [thread overview]
Message-ID: <87v9g3a4j0.fsf@gnu.org> (raw)
In-Reply-To: <87k0wprcs6.fsf@gnu.org> ("Ludovic Courtès"'s message of "Sat, 19 Sep 2020 17:45:13 +0200")
[-- Attachment #1: Type: text/plain, Size: 640 bytes --]
Ludovic Courtès <ludo@gnu.org> skribis:
> Ludovic Courtès <ludovic.courtes@inria.fr> skribis:
>
>> Indeed, we can see ‘stat’ calls passed raw /gnu/store file names from
>> RUNPATH entries (instead of /tmp/fakechroot-test/gnu/store), suggesting
>> that ‘la_objsearch’ didn’t have a chance to rewrite them:
>
> This is probably an ld.so bug:
>
> https://sourceware.org/bugzilla/show_bug.cgi?id=26634
The patch below provides a fix/workaround for glibc, confirming the
hypothesis above. (I don’t think we should apply this patch though,
rather we’ll work around the issue in ‘guix pack’.)
Ludo’.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: Type: text/x-patch, Size: 5825 bytes --]
diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index c83775d8ee..fa4da801af 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -685,6 +685,7 @@ the store.")
(package
(name "glibc")
(version "2.31")
+ (replacement glibc-2.31/fixed)
(source (origin
(method url-fetch)
(uri (string-append "mirror://gnu/glibc/glibc-" version ".tar.xz"))
@@ -933,6 +934,15 @@ with the Linux kernel.")
(license lgpl2.0+)
(home-page "https://www.gnu.org/software/libc/")))
+(define-public glibc-2.31/fixed
+ (package
+ (inherit glibc)
+ (version "2.3A")
+ (source (origin
+ (inherit (package-source glibc))
+ (patches (append (search-patches "glibc-audit-stat.patch")
+ (origin-patches (package-source glibc))))))))
+
;; Below are old libc versions, which we use mostly to build locale data in
;; the old format (which the new libc cannot cope with.)
--- /dev/null
+++ b/gnu/packages/patches/glibc-audit-stat.patch
@@ -0,0 +1,126 @@
+diff --git a/elf/dl-load.c b/elf/dl-load.c
+index a6b80f9395..9daa32f76b 100644
+--- a/elf/dl-load.c
++++ b/elf/dl-load.c
+@@ -1461,11 +1461,15 @@ print_search_path (struct r_search_path_elem **list,
+ user might want to know about this.
+
+ If FD is not -1, then the file is already open and FD refers to it.
+- In that case, FD is consumed for both successful and error returns. */
++ In that case, FD is consumed for both successful and error returns.
++
++ Set *CHANGED_BY_AUDIT to true if the audit module provided a file name
++ different from NAME. */
+ static int
+ open_verify (const char *name, int fd,
+ struct filebuf *fbp, struct link_map *loader,
+- int whatcode, int mode, bool *found_other_class, bool free_name)
++ int whatcode, int mode, bool *found_other_class, bool free_name,
++ bool *changed_by_audit)
+ {
+ /* This is the expected ELF header. */
+ #define ELF32_CLASS ELFCLASS32
+@@ -1500,6 +1504,8 @@ open_verify (const char *name, int fd,
+ const char *errstring = NULL;
+ int errval = 0;
+
++ *changed_by_audit = false;
++
+ #ifdef SHARED
+ /* Give the auditing libraries a chance. */
+ if (__glibc_unlikely (GLRO(dl_naudit) > 0) && whatcode != 0
+@@ -1521,12 +1527,19 @@ open_verify (const char *name, int fd,
+ afct = afct->next;
+ }
+
+- if (fd != -1 && name != original_name && strcmp (name, original_name))
++ if (name != original_name && strcmp (name, original_name))
+ {
+- /* An audit library changed what we're supposed to open,
+- so FD no longer matches it. */
+- __close_nocancel (fd);
+- fd = -1;
++ /* Tell the caller we're looking at something different from
++ ORIGINAL_NAME. */
++ *changed_by_audit = true;
++
++ if (fd != -1)
++ {
++ /* An audit library changed what we're supposed to open, so FD
++ no longer matches it. */
++ __close_nocancel (fd);
++ fd = -1;
++ }
+ }
+ }
+ #endif
+@@ -1782,6 +1795,7 @@ open_path (const char *name, size_t namelen, int mode,
+ char *edp;
+ int here_any = 0;
+ int err;
++ bool changed_by_audit;
+
+ /* If we are debugging the search for libraries print the path
+ now if it hasn't happened now. */
+@@ -1810,16 +1824,19 @@ open_path (const char *name, size_t namelen, int mode,
+ _dl_debug_printf (" trying file=%s\n", buf);
+
+ fd = open_verify (buf, -1, fbp, loader, whatcode, mode,
+- found_other_class, false);
++ found_other_class, false,
++ &changed_by_audit);
+ if (this_dir->status[cnt] == unknown)
+ {
+ if (fd != -1)
+ this_dir->status[cnt] = existing;
+ /* Do not update the directory information when loading
+ auditing code. We must try to disturb the program as
+- little as possible. */
+- else if (loader == NULL
+- || GL(dl_ns)[loader->l_ns]._ns_loaded->l_auditing == 0)
++ little as possible. Additionally, if the audit module
++ change the file name, keep directory information as is. */
++ else if ((loader == NULL
++ || GL(dl_ns)[loader->l_ns]._ns_loaded->l_auditing == 0)
++ && !changed_by_audit)
+ {
+ /* We failed to open machine dependent library. Let's
+ test whether there is any directory at all. */
+@@ -2064,10 +2081,11 @@ _dl_map_object (struct link_map *loader, const char *name,
+ realname = _dl_sysdep_open_object (name, namelen, &fd);
+ if (realname != NULL)
+ {
++ bool changed_by_audit;
+ fd = open_verify (realname, fd,
+ &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
+ LA_SER_CONFIG, mode, &found_other_class,
+- false);
++ false, &changed_by_audit);
+ if (fd == -1)
+ free (realname);
+ }
+@@ -2118,10 +2136,11 @@ _dl_map_object (struct link_map *loader, const char *name,
+
+ if (cached != NULL)
+ {
++ bool changed_by_audit;
+ fd = open_verify (cached, -1,
+ &fb, loader ?: GL(dl_ns)[nsid]._ns_loaded,
+ LA_SER_CONFIG, mode, &found_other_class,
+- false);
++ false, &changed_by_audit);
+ if (__glibc_likely (fd != -1))
+ realname = cached;
+ else
+@@ -2153,9 +2172,10 @@ _dl_map_object (struct link_map *loader, const char *name,
+ fd = -1;
+ else
+ {
++ bool changed_by_audit;
+ fd = open_verify (realname, -1, &fb,
+ loader ?: GL(dl_ns)[nsid]._ns_loaded, 0, mode,
+- &found_other_class, true);
++ &found_other_class, true, &changed_by_audit);
+ if (__glibc_unlikely (fd == -1))
+ free (realname);
+ }
next prev parent reply other threads:[~2020-09-24 10:19 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-18 13:28 bug#43491: Fakechroot execution engine can fail to find libraries Ludovic Courtès
2020-09-18 16:04 ` Ludovic Courtès
2020-09-19 15:45 ` Ludovic Courtès
2020-09-24 9:49 ` Ludovic Courtès [this message]
2020-10-01 10:53 ` Ludovic Courtès
[not found] ` <handler.43491.D43491.160154964712299.notifdone@debbugs.gnu.org>
2023-03-17 17:03 ` Ludovic Courtès
2023-03-17 22:26 ` Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://guix.gnu.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87v9g3a4j0.fsf@gnu.org \
--to=ludo@gnu.org \
--cc=43491@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).