From: Markus Mayer <mmayer@broadcom.com>
To: Musl Mailing List <musl@lists.openwall.com>
Cc: Colin Cross <ccross@android.com>, Colin Cross <ccross@google.com>,
Markus Mayer <mmayer@broadcom.com>
Subject: [musl] [PATCH 1/1] Ignore incorrect elf architecture libraries
Date: Fri, 5 Jul 2024 14:12:28 -0700 [thread overview]
Message-ID: <20240705211232.2718532-2-mmayer@broadcom.com> (raw)
In-Reply-To: <20240705211232.2718532-1-mmayer@broadcom.com>
From: Colin Cross <ccross@android.com>
In multilib systems LD_LIBRARY_PATH is sometimes set to a list that
contains both the lib32 and lib64 directories, for example when
running code that may execute 32-bit or 64-bit subprocesses or both.
Musl's dynamic loader aborts searching a path list when it finds any
library that is not loadable, preventing searching the other multilib
directory.
Modify the loader to continue searching when a file is found that is
a valid elf file but for the an elf machine or class that differs from
that of the loader itself.
---
ldso/dynlink.c | 77 +++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 61 insertions(+), 16 deletions(-)
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 324aa85919f0..2f1ac7e9d089 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -68,6 +68,8 @@ struct dso {
size_t *dynv;
struct dso *next, *prev;
+ int elfmachine;
+ int elfclass;
Phdr *phdr;
int phnum;
size_t phentsize;
@@ -684,6 +686,19 @@ static void unmap_library(struct dso *dso)
}
}
+static int verify_elf_magic(const Ehdr* eh) {
+ return eh->e_ident[0] == ELFMAG0 &&
+ eh->e_ident[1] == ELFMAG1 &&
+ eh->e_ident[2] == ELFMAG2 &&
+ eh->e_ident[3] == ELFMAG3;
+}
+
+/* Verifies that an elf header's machine and class match the loader */
+static int verify_elf_arch(const Ehdr* eh) {
+ return eh->e_machine == ldso.elfmachine &&
+ eh->e_ident[EI_CLASS] == ldso.elfclass;
+}
+
static void *map_library(int fd, struct dso *dso)
{
Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
@@ -706,6 +721,10 @@ static void *map_library(int fd, struct dso *dso)
if (l<0) return 0;
if (l<sizeof *eh || (eh->e_type != ET_DYN && eh->e_type != ET_EXEC))
goto noexec;
+ if (!verify_elf_magic(eh)) goto noexec;
+ if (!verify_elf_arch(eh)) goto noexec;
+ dso->elfmachine = eh->e_machine;
+ dso->elfclass = eh->e_ident[EI_CLASS];
phsize = eh->e_phentsize * eh->e_phnum;
if (phsize > sizeof buf - sizeof *eh) {
allocated_buf = malloc(phsize);
@@ -870,29 +889,53 @@ error:
return 0;
}
-static int path_open(const char *name, const char *s, char *buf, size_t buf_size)
+static int path_open_library(const char *name, const char *s, char *buf, size_t buf_size)
{
size_t l;
int fd;
+ const char *p;
for (;;) {
s += strspn(s, ":\n");
+ p = s;
l = strcspn(s, ":\n");
if (l-1 >= INT_MAX) return -1;
- if (snprintf(buf, buf_size, "%.*s/%s", (int)l, s, name) < buf_size) {
- if ((fd = open(buf, O_RDONLY|O_CLOEXEC))>=0) return fd;
- switch (errno) {
- case ENOENT:
- case ENOTDIR:
- case EACCES:
- case ENAMETOOLONG:
- break;
- default:
- /* Any negative value but -1 will inhibit
- * futher path search. */
+ s += l;
+ if (snprintf(buf, buf_size, "%.*s/%s", (int)l, p, name) < buf_size) {
+ fd = open(buf, O_RDONLY|O_CLOEXEC);
+ if (fd < 0) {
+ switch (errno) {
+ case ENOENT:
+ case ENOTDIR:
+ case EACCES:
+ case ENAMETOOLONG:
+ /* Keep searching in path list. */
+ continue;
+ default:
+ /* Any negative value but -1 will
+ * inhibit further path search in
+ * load_library. */
+ return -2;
+ }
+ }
+ Ehdr eh;
+ ssize_t n = pread(fd, &eh, sizeof(eh), 0);
+ /* If the elf file is invalid return -2 to inhibit
+ * further path search in load_library. */
+ if (n < 0 ||
+ n != sizeof eh ||
+ !verify_elf_magic(&eh)) {
+ close(fd);
return -2;
}
+ /* If the elf file has a valid header but is for the
+ * wrong architecture ignore it and keep searching the
+ * path list. */
+ if (!verify_elf_arch(&eh)) {
+ close(fd);
+ continue;
+ }
+ return fd;
}
- s += l;
}
}
@@ -1116,12 +1159,12 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
}
if (strlen(name) > NAME_MAX) return 0;
fd = -1;
- if (env_path) fd = path_open(name, env_path, buf, sizeof buf);
+ if (env_path) fd = path_open_library(name, env_path, buf, sizeof buf);
for (p=needed_by; fd == -1 && p; p=p->needed_by) {
if (fixup_rpath(p, buf, sizeof buf) < 0)
fd = -2; /* Inhibit further search. */
if (p->rpath)
- fd = path_open(name, p->rpath, buf, sizeof buf);
+ fd = path_open_library(name, p->rpath, buf, sizeof buf);
}
if (fd == -1) {
if (!sys_path) {
@@ -1160,7 +1203,7 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
}
}
if (!sys_path) sys_path = "/lib:/usr/local/lib:/usr/lib";
- fd = path_open(name, sys_path, buf, sizeof buf);
+ fd = path_open_library(name, sys_path, buf, sizeof buf);
}
pathname = buf;
}
@@ -1732,6 +1775,8 @@ hidden void __dls2(unsigned char *base, size_t *sp)
ldso.phnum = ehdr->e_phnum;
ldso.phdr = laddr(&ldso, ehdr->e_phoff);
ldso.phentsize = ehdr->e_phentsize;
+ ldso.elfmachine = ehdr->e_machine;
+ ldso.elfclass = ehdr->e_ident[EI_CLASS];
search_vec(auxv, &ldso_page_size, AT_PAGESZ);
kernel_mapped_dso(&ldso);
decode_dyn(&ldso);
--
2.45.2
next prev parent reply other threads:[~2024-07-05 21:13 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-05 21:12 [musl] [PATCH 0/1] " Markus Mayer
2024-07-05 21:12 ` Markus Mayer [this message]
2024-07-23 21:08 ` [musl] [PATCH 1/1] " Szabolcs Nagy
2024-07-23 22:53 ` Rich Felker
2024-09-26 19:35 ` Markus Mayer
2024-10-09 10:14 ` Szabolcs Nagy
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
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240705211232.2718532-2-mmayer@broadcom.com \
--to=mmayer@broadcom.com \
--cc=ccross@android.com \
--cc=ccross@google.com \
--cc=musl@lists.openwall.com \
/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.vuxu.org/mirror/musl/
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 NNTP newsgroup(s).