Sometimes zero is a valid value for getauxval (e.g. AT_EXECFD). Make sure that we can distinguish between a valid zero value and a not found entry by setting errno.
Ignore getauxval from sys/auxv.h on glibc < 2.19 because it does not set errno. Signed-off-by: Vivian Wang <[email protected]> --- util/getauxval.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/util/getauxval.c b/util/getauxval.c index b124107d61..f1008bdc59 100644 --- a/util/getauxval.c +++ b/util/getauxval.c @@ -24,7 +24,13 @@ #include "qemu/osdep.h" -#ifdef CONFIG_GETAUXVAL +/* If glibc < 2.19, getauxval can't be used because it does not set errno if + entry is not found. */ +#if defined(CONFIG_GETAUXVAL) && \ + (!defined(__GLIBC__) \ + || __GLIBC__ > 2 \ + || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 19)) + /* Don't inline this in qemu/osdep.h, because pulling in <sys/auxv.h> for the system declaration of getauxval pulls in the system <elf.h>, which conflicts with qemu's version. */ @@ -95,6 +101,7 @@ unsigned long qemu_getauxval(unsigned long type) } } + errno = ENOENT; return 0; } @@ -104,7 +111,9 @@ unsigned long qemu_getauxval(unsigned long type) unsigned long qemu_getauxval(unsigned long type) { unsigned long aux = 0; - elf_aux_info(type, &aux, sizeof(aux)); + int ret = elf_aux_info(type, &aux, sizeof(aux)); + if (ret != 0) + errno = ret; return aux; } @@ -112,6 +121,7 @@ unsigned long qemu_getauxval(unsigned long type) unsigned long qemu_getauxval(unsigned long type) { + errno = ENOSYS; return 0; } -- 2.45.1
