diff mbox series

[v3,1/2] linux: wait4: Fix incorrect return value comparison

Message ID 20200409201154.3365671-1-alistair.francis@wdc.com
State New
Headers show
Series [v3,1/2] linux: wait4: Fix incorrect return value comparison | expand

Commit Message

develop--- via Libc-alpha April 9, 2020, 8:11 p.m. UTC
Patch 600f00b "linux: Use long time_t for wait4/getrusage" introduced
two bugs:
 - The usage32 struct was set if the wait4 syscall had an error.
 - For 32-bit systems the usage struct was set even if it was specified
   as NULL.

This patch fixes the two issues.
---
 sysdeps/unix/sysv/linux/wait4.c | 32 ++++++++++++++++++++------------
 1 file changed, 20 insertions(+), 12 deletions(-)

Comments

develop--- via Libc-alpha April 9, 2020, 8:52 p.m. UTC | #1
On 09/04/2020 17:11, Alistair Francis via Libc-alpha wrote:
> Patch 600f00b "linux: Use long time_t for wait4/getrusage" introduced
> two bugs:
>  - The usage32 struct was set if the wait4 syscall had an error.
>  - For 32-bit systems the usage struct was set even if it was specified
>    as NULL.
> 
> This patch fixes the two issues.

Ok with the changes below.

> ---
>  sysdeps/unix/sysv/linux/wait4.c | 32 ++++++++++++++++++++------------
>  1 file changed, 20 insertions(+), 12 deletions(-)
> 
> diff --git a/sysdeps/unix/sysv/linux/wait4.c b/sysdeps/unix/sysv/linux/wait4.c
> index d14bd4da27..21eb154b72 100644
> --- a/sysdeps/unix/sysv/linux/wait4.c
> +++ b/sysdeps/unix/sysv/linux/wait4.c
> @@ -29,14 +29,18 @@ __wait4_time64 (pid_t pid, int *stat_loc, int options, struct __rusage64 *usage)
>  # if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
>    return SYSCALL_CANCEL (wait4, pid, stat_loc, options, usage);
>  # else
> -  struct __rusage32 usage32;
> -  pid_t ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options, &usage32);
> -
> -  if (ret != 0)
> -    return ret;
> +  pid_t ret;
>  
>    if (usage != NULL)
> -    rusage32_to_rusage64 (&usage32, usage);
> +    {
> +      struct __rusage32 usage32;
> +        ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options, &usage32);

Indentation seems off.

> +
> +      if (ret > 0)
> +        rusage32_to_rusage64 (&usage32, usage);> +    }
> +  else
> +    ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options, NULL);

I think there is no much gain in optimizing stack usage here,
I would prefer to simplify to just:

  struct __rusage32 usage32;
  ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options,
                        usage != NULL ? &usage32 : NULL);
  if (ret > 0 && usage != NULL)
    rusage32_to_rusage64 (&usage32, usage);


>  
>    return ret;
>  # endif
> @@ -114,15 +118,19 @@ libc_hidden_def (__wait4_time64)
>  pid_t
>  __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
>  {
> -  pid_t ret ;
> -  struct __rusage64 usage64;
> +  pid_t ret;
>  
> -  ret = __wait4_time64 (pid, stat_loc, options, &usage64);
> +  if (usage != NULL)
> +    {
> +      struct __rusage64 usage64;
>  
> -  if (ret != 0)
> -    return ret;
> +      ret = __wait4_time64 (pid, stat_loc, options, &usage64);
>  
> -  rusage64_to_rusage (&usage64, usage);
> +      if (ret > 0)
> +        rusage64_to_rusage (&usage64, usage);
> +    }
> +  else
> +    ret = __wait4_time64 (pid, stat_loc, options, NULL);
>  
>    return ret;
>  }
> 

Same as before:

  struct __rusage64 usage64;
  ret = __wait4_time64 (pid, stat_loc, options,
                        usage != NULL ? &usage64 : NULL);
  if (ret > 0 && usage != 0)
    rusage64_to_rusage (&usage64, usage);
diff mbox series

Patch

diff --git a/sysdeps/unix/sysv/linux/wait4.c b/sysdeps/unix/sysv/linux/wait4.c
index d14bd4da27..21eb154b72 100644
--- a/sysdeps/unix/sysv/linux/wait4.c
+++ b/sysdeps/unix/sysv/linux/wait4.c
@@ -29,14 +29,18 @@  __wait4_time64 (pid_t pid, int *stat_loc, int options, struct __rusage64 *usage)
 # if __KERNEL_OLD_TIMEVAL_MATCHES_TIMEVAL64
   return SYSCALL_CANCEL (wait4, pid, stat_loc, options, usage);
 # else
-  struct __rusage32 usage32;
-  pid_t ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options, &usage32);
-
-  if (ret != 0)
-    return ret;
+  pid_t ret;
 
   if (usage != NULL)
-    rusage32_to_rusage64 (&usage32, usage);
+    {
+      struct __rusage32 usage32;
+        ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options, &usage32);
+
+      if (ret > 0)
+        rusage32_to_rusage64 (&usage32, usage);
+    }
+  else
+    ret = SYSCALL_CANCEL (wait4, pid, stat_loc, options, NULL);
 
   return ret;
 # endif
@@ -114,15 +118,19 @@  libc_hidden_def (__wait4_time64)
 pid_t
 __wait4 (pid_t pid, int *stat_loc, int options, struct rusage *usage)
 {
-  pid_t ret ;
-  struct __rusage64 usage64;
+  pid_t ret;
 
-  ret = __wait4_time64 (pid, stat_loc, options, &usage64);
+  if (usage != NULL)
+    {
+      struct __rusage64 usage64;
 
-  if (ret != 0)
-    return ret;
+      ret = __wait4_time64 (pid, stat_loc, options, &usage64);
 
-  rusage64_to_rusage (&usage64, usage);
+      if (ret > 0)
+        rusage64_to_rusage (&usage64, usage);
+    }
+  else
+    ret = __wait4_time64 (pid, stat_loc, options, NULL);
 
   return ret;
 }