|
|
Message-ID: <n1FH_ABRqLH5azVtlHjGr7zNxzSeSSkTseltE1X-55Zjb5Lv2j_ABU33FGvFLFDc6qK1osA8YMzog5D2gs6qmgCL2d8WePdhY3yYQiZevtE=@harmenstoppels.nl>
Date: Sun, 20 Mar 2022 14:19:23 +0000
From: Harmen Stoppels <me@...menstoppels.nl>
To: "musl@...ts.openwall.com" <musl@...ts.openwall.com>
Subject: [PATCH] dynlink.c: locate ld-musl-<arch>.path better.
Fixes an issue where the dynamic loader can't locate the
`ld-musl-<arch>.path` file when the interpreter is not a normalized
path. The following works after this commit:
```
./path/to/ld-musl-<arch>.so.1 ./exe
/absolute/path/to////ld-musl-<arch>.so.1 ./exe
/absolute/path/to/./ld-musl-<arch>.so.1 ./exe
```
The `ld-musl-<arch>.path` file is now located by simply appending
`/../etc/ld-musl-<arch>.path` to the directory name of `ldso.name`, or
falls back to `/etc/ld-musl-<arch>.path` when no directory separator is
found in `ldso.name`.
This means that there's currently one limitation where
```
PATH="/absolute/path/to/loader/dir:$PATH" ld-musl-<arch.so.1> ./exe
```
still fails to locate `ld-musl-<arch>.path` relative to the dynamic
loader's path.
---
ldso/dynlink.c | 29 +++++++++++------------------
1 file changed, 11 insertions(+), 18 deletions(-)
diff --git a/ldso/dynlink.c b/ldso/dynlink.c
index 5b9c8be4..5a508ddf 100644
--- a/ldso/dynlink.c
+++ b/ldso/dynlink.c
@@ -1061,25 +1061,18 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
}
if (fd == -1) {
if (!sys_path) {
- char *prefix = 0;
- size_t prefix_len;
- if (ldso.name[0]=='/') {
- char *s, *t, *z;
- for (s=t=z=ldso.name; *s; s++)
- if (*s=='/') z=t, t=s;
- prefix_len = z-ldso.name;
- if (prefix_len < PATH_MAX)
- prefix = ldso.name;
+ /* etc_ldso_path is <dir of ld.so>/../etc/ld-musl-<arch>.path when
+ * we have a path for ld.so, otherwise fall back to
+ * /etc/ld-musl-<arch>.path. */
+ char suffix[] = "/etc/ld-musl-" LDSO_ARCH ".path";
+ char *ldso_dir = strrchr(ldso.name, '/');
+ size_t prefix_len = ldso_dir ? ldso_dir - ldso.name + 3 : 0;
+ char etc_ldso_path[prefix_len + sizeof suffix];
+ if (ldso_dir) {
+ memcpy(etc_ldso_path, ldso.name, prefix_len - 2);
+ memcpy(etc_ldso_path + prefix_len - 2, "..", 2);
}
- if (!prefix) {
- prefix = "";
- prefix_len = 0;
- }
- char etc_ldso_path[prefix_len + 1
- + sizeof "/etc/ld-musl-" LDSO_ARCH ".path"];
- snprintf(etc_ldso_path, sizeof etc_ldso_path,
- "%.*s/etc/ld-musl-" LDSO_ARCH ".path",
- (int)prefix_len, prefix);
+ memcpy(etc_ldso_path + prefix_len, suffix, sizeof suffix);
fd = open(etc_ldso_path, O_RDONLY|O_CLOEXEC);
if (fd>=0) {
size_t n = 0;
--
2.25.1
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.