From ba2caa8a3824011f42b67327917e8285784e016e Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Sat, 27 Apr 2024 15:25:09 +0100 Subject: [PATCH] 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 --- src/basic/build-path.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/basic/build-path.c b/src/basic/build-path.c index 8ddef7b2dd..b5972658df 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) { -- 2.25.1