diff mbox

linux-user: fix getrusage and wait4 failures with invalid rusage struct

Message ID 1396977870-108623-1-git-send-email-petar.jovanovic@rt-rk.com
State New
Headers show

Commit Message

Petar Jovanovic April 8, 2014, 5:24 p.m. UTC
From: Petar Jovanovic <petar.jovanovic@imgtec.com>

Implementations of system calls getrusage and wait4 have not previously
handled correctly cases when incorrect address of struct rusage is
passed.
This change makes sure return values are correctly set for these cases.

Signed-off-by: Petar Jovanovic <petar.jovanovic@imgtec.com>
---
 linux-user/syscall.c |   11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

Comments

Andreas Färber May 5, 2014, 9:55 a.m. UTC | #1
Am 08.04.2014 19:24, schrieb Petar Jovanovic:
> From: Petar Jovanovic <petar.jovanovic@imgtec.com>
> 
> Implementations of system calls getrusage and wait4 have not previously
> handled correctly cases when incorrect address of struct rusage is
> passed.
> This change makes sure return values are correctly set for these cases.
> 
> Signed-off-by: Petar Jovanovic <petar.jovanovic@imgtec.com>
> ---
>  linux-user/syscall.c |   11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 9864813..fc52f0b 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -6309,7 +6309,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>              struct rusage rusage;
>              ret = get_errno(getrusage(arg1, &rusage));
>              if (!is_error(ret)) {
> -                host_to_target_rusage(arg2, &rusage);
> +                ret = host_to_target_rusage(arg2, &rusage);
>              }
>          }
>          break;

Why do you always set ret here ...

> @@ -6974,6 +6974,7 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>              abi_long status_ptr = arg2;
>              struct rusage rusage, *rusage_ptr;
>              abi_ulong target_rusage = arg4;
> +            abi_long rusage_err;
>              if (target_rusage)
>                  rusage_ptr = &rusage;
>              else
> @@ -6985,8 +6986,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
>                      if (put_user_s32(status, status_ptr))
>                          goto efault;
>                  }
> -                if (target_rusage)
> -                    host_to_target_rusage(target_rusage, &rusage);
> +                if (target_rusage) {
> +                    rusage_err = host_to_target_rusage(target_rusage, &rusage);
> +                    if (rusage_err) {
> +                        ret = rusage_err;
> +                    }
> +                }
>              }
>          }
>          break;

... but only on error here? Isn't obvious from the commit message.

Regards,
Andreas
Petar Jovanovic May 5, 2014, 10:12 a.m. UTC | #2

diff mbox

Patch

diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index 9864813..fc52f0b 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -6309,7 +6309,7 @@  abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             struct rusage rusage;
             ret = get_errno(getrusage(arg1, &rusage));
             if (!is_error(ret)) {
-                host_to_target_rusage(arg2, &rusage);
+                ret = host_to_target_rusage(arg2, &rusage);
             }
         }
         break;
@@ -6974,6 +6974,7 @@  abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
             abi_long status_ptr = arg2;
             struct rusage rusage, *rusage_ptr;
             abi_ulong target_rusage = arg4;
+            abi_long rusage_err;
             if (target_rusage)
                 rusage_ptr = &rusage;
             else
@@ -6985,8 +6986,12 @@  abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
                     if (put_user_s32(status, status_ptr))
                         goto efault;
                 }
-                if (target_rusage)
-                    host_to_target_rusage(target_rusage, &rusage);
+                if (target_rusage) {
+                    rusage_err = host_to_target_rusage(target_rusage, &rusage);
+                    if (rusage_err) {
+                        ret = rusage_err;
+                    }
+                }
             }
         }
         break;