diff mbox series

[1/2] util/getauxval: Ensure setting errno if not found

Message ID 20240721090817.120888-2-uwu@dram.page
State New
Headers show
Series linux-user: Fix handling when AT_EXECFD is 0 | expand

Commit Message

Vivian Wang July 21, 2024, 9:08 a.m. UTC
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 <uwu@dram.page>
---
 util/getauxval.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

Comments

Vivian Wang July 22, 2024, 8:24 a.m. UTC | #1
On 7/22/24 08:18, Xingtao Yao (Fujitsu) wrote:
>
>> -----Original Message-----
>> From: qemu-devel-bounces+yaoxt.fnst=fujitsu.com@nongnu.org
>> <qemu-devel-bounces+yaoxt.fnst=fujitsu.com@nongnu.org> On Behalf Of Vivian
>> Wang
>> Sent: Sunday, July 21, 2024 5:08 PM
>> To: qemu-devel@nongnu.org
>> Cc: Vivian Wang <uwu@dram.page>; Richard Henderson <rth@twiddle.net>;
>> Laurent Vivier <laurent@vivier.eu>
>> Subject: [PATCH 1/2] util/getauxval: Ensure setting errno if not found
>>
>> 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 <uwu@dram.page>
>> ---
>>  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))
> you can use GLIB_CHECK_VERSION(2, 19, 0) instead
That wouldn't work. I'm testing for glibc, not glib.
>> +
>>  /* 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
>>
Richard Henderson July 22, 2024, 11:24 p.m. UTC | #2
On 7/21/24 19:08, Vivian Wang wrote:
> 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 <uwu@dram.page>
> ---
>   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))

Version 2.19 is so long ago that all supported OS releases have something newer.  For 
Alpine Linux using musl, the first commit of getauxval had the errno setting.

Therefore we don't need this check.

> @@ -95,6 +101,7 @@ unsigned long qemu_getauxval(unsigned long type)
>           }
>       }
>   
> +    errno = ENOENT;
>       return 0;
>   }

Ok.

> @@ -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;

Braces required.

>       return aux;
>   }
>   
> @@ -112,6 +121,7 @@ unsigned long qemu_getauxval(unsigned long type)
>   
>   unsigned long qemu_getauxval(unsigned long type)
>   {
> +    errno = ENOSYS;
>       return 0;
>   }

Ok.


r~
diff mbox series

Patch

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;
 }