|
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.