qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] linux-user: fix "really futimens" condition in


From: Peter Maydell
Subject: Re: [Qemu-devel] [PATCH] linux-user: fix "really futimens" condition in sys_utimensat()
Date: Fri, 15 Jul 2016 18:59:18 +0100

On 15 July 2016 at 18:43, Peter Maydell <address@hidden> wrote:
> In some configurations we implement sys_utimensat() via a wrapper
> that calls either futimens() or utimensat(), depending on the
> arguments (to handle a case where the Linux syscall API diverges
> from the glibc API). Fix a corner case in this handling:
> if the syscall is passed a NULL pathname and dirfd == AT_FDCWD,
> then it must fail with EFAULT. We can't handle this by passing
> it to glibc utimensat() because at the libc level a NULL
> pathname is failed with EINVAL, and we can't handle it by
> passing to futimens() because that would fail with EBADF.
> So special case it and return EFAULT directly from the wrapper.
>
> This means that if the guest calls utimes() with a NULL pathname
> and guest glibc converts that into a syscall utimensat(AT_FDCWD,
> NULL, ...) then we correctly fail it with EFAULT.
>
> Signed-off-by: Peter Maydell <address@hidden>
> ---
>  linux-user/syscall.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
>
> diff --git a/linux-user/syscall.c b/linux-user/syscall.c
> index 0e87157..61ea58b 100644
> --- a/linux-user/syscall.c
> +++ b/linux-user/syscall.c
> @@ -367,10 +367,15 @@ static int sys_getcwd1(char *buf, size_t size)
>  static int sys_utimensat(int dirfd, const char *pathname,
>      const struct timespec times[2], int flags)
>  {
> -    if (pathname == NULL)
> +    if (pathname == NULL) {
> +        if (dirfd == AT_FDCWD) {
> +            errno = EFAULT;
> +            return -1;
> +        }
>          return futimens(dirfd, times);
> -    else
> +    } else {
>          return utimensat(dirfd, pathname, times, flags);
> +    }
>  }
>  #elif defined(__NR_utimensat)
>  #define __NR_sys_utimensat __NR_utimensat

There turns out to be another annoying corner case here, which is
when pathname == NULL, dirfd != AT_FDCWD and the flags include
AT_SYMLINK_NOFOLLOW -- this is supposed to fail EINVAL. I'll
have a look at that next week and see whether it's best fixed
in the same patch as this case or with a followup patch...

thanks
-- PMM



reply via email to

[Prev in Thread] Current Thread [Next in Thread]