From: Luca Boccassi Date: Sat, 27 Apr 2024 14:25:09 +0000 (+0100) Subject: build-path: fix SIGSEGV on RISC-V and MIPS X-Git-Tag: v256-rc2~145 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ba2caa8a3824011f42b67327917e8285784e016e;p=thirdparty%2Fsystemd.git build-path: fix SIGSEGV on RISC-V and MIPS On RISC-V and MIPS DT_STRTAB is an offset, not a full address. Follow-up for 91d149cfb45fc2fad7ce18fb651297ee50ecc1f8 --- diff --git a/src/basic/build-path.c b/src/basic/build-path.c index 8ddef7b2dd5..b5972658dfe 100644 --- a/src/basic/build-path.c +++ b/src/basic/build-path.c @@ -12,7 +12,7 @@ #include "process-util.h" #include "unistd.h" -static int get_runpath_from_dynamic(const ElfW(Dyn) *d, const char **ret) { +static int get_runpath_from_dynamic(const ElfW(Dyn) *d, ElfW(Addr) bias, const char **ret) { size_t runpath_index = SIZE_MAX, rpath_index = SIZE_MAX; const char *strtab = NULL; @@ -33,7 +33,14 @@ static int get_runpath_from_dynamic(const ElfW(Dyn) *d, const char **ret) { break; case DT_STRTAB: - strtab = (const char *) d->d_un.d_val; + /* On MIPS and RISC-V DT_STRTAB records an offset, not a valid address, so it has to be adjusted + * using the bias calculated earlier. */ + if (d->d_un.d_val != 0) + strtab = (const char *) ((uintptr_t) d->d_un.d_val +#if defined(__mips__) || defined(__riscv) + + bias +#endif + ); break; } @@ -45,7 +52,7 @@ static int get_runpath_from_dynamic(const ElfW(Dyn) *d, const char **ret) { if (!strtab) return -ENOTRECOVERABLE; - /* According to dl.so runpath wins of both runpath and rpath are defined. */ + /* According to ld.so runpath wins if both runpath and rpath are defined. */ if (runpath_index != SIZE_MAX) { if (ret) *ret = strtab + runpath_index; @@ -111,7 +118,7 @@ static int get_runpath(const char **ret) { if (!found_dyn) return -ENOTRECOVERABLE; - return get_runpath_from_dynamic((const ElfW(Dyn)*) (bias + dyn), ret); + return get_runpath_from_dynamic((const ElfW(Dyn)*) (bias + dyn), bias, ret); } int get_build_exec_dir(char **ret) {