coreutils
[Top][All Lists]
Advanced

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

Re: [PATCH] stat: fallback if statx() is not available


From: Jeff Layton
Subject: Re: [PATCH] stat: fallback if statx() is not available
Date: Wed, 09 Sep 2020 15:35:23 -0400
User-agent: Evolution 3.36.5 (3.36.5-1.fc32)

On Tue, 2020-09-08 at 10:56 +0300, Ville Heikkinen wrote:
> In case statx() returns EPERM or ENOSYS, fallback to use fstat(),
> lstat() and stat() instead.
> 
> It's possible that the statx() is not functional e.g. due to the
> used seccomp filters. Because of that, it would be good to fallback
> to use the other methods to retrieve the stat info.
> ---
>  src/stat.c | 37 +++++++++++++++++++++++++++++--------
>  1 file changed, 29 insertions(+), 8 deletions(-)
> 

Does this actually fix anything? When the problem with seccomp was
discovered, the task would continue to get back

> diff --git a/src/stat.c b/src/stat.c
> index 4e6c2aa86..f53f98c3d 100644
> --- a/src/stat.c
> +++ b/src/stat.c
> @@ -246,6 +246,10 @@ static char const *trailing_delim = "";
>  static char const *decimal_point;
>  static size_t decimal_point_len;
>  
> +#if USE_STATX
> +static bool use_stat = false;
> +#endif
> +
>  static bool
>  print_stat (char *pformat, size_t prefix_len, unsigned int m,
>              int fd, char const *filename, void const *data);
> @@ -1329,9 +1333,13 @@ format_to_mask (char const *format)
>    return mask;
>  }
>  
> +static bool ATTRIBUTE_WARN_UNUSED_RESULT
> +do_stat (char const *filename, char const *format,
> +         char const *format2);
> +
>  /* statx the file and print what we find */
>  static bool ATTRIBUTE_WARN_UNUSED_RESULT
> -do_stat (char const *filename, char const *format, char const *format2)
> +do_statx (char const *filename, char const *format, char const *format2)
>  {
>    int fd = STREQ (filename, "-") ? 0 : AT_FDCWD;
>    int flags = 0;
> @@ -1360,6 +1368,11 @@ do_stat (char const *filename, char const *format, 
> char const *format2)
>    fd = statx (fd, pathname, flags, format_to_mask (format), &stx);
>    if (fd < 0)
>      {
> +      if (errno == EPERM || errno == ENOSYS)
> +        {
> +          use_stat = true;
> +          return do_stat (filename, format, format2);
> +        }

Does this actually work around the seccomp bugs? What we found here was
that once you tried to use statx with the broken seccomp code all
syscalls issued by the task would get back -ENOSYS afterward.

See:

    https://bugzilla.redhat.com/show_bug.cgi?id=1762578

Is there a different bug you're trying to fix?


>        if (flags & AT_EMPTY_PATH)
>          error (0, errno, _("cannot stat standard input"));
>        else
> @@ -1378,7 +1391,7 @@ do_stat (char const *filename, char const *format, char 
> const *format2)
>    return ! fail;
>  }
>  
> -#else /* USE_STATX */
> +#endif /* USE_STATX */
>  
>  static struct timespec
>  get_birthtime (int fd, char const *filename, struct stat const *st)
> @@ -1449,7 +1462,6 @@ do_stat (char const *filename, char const *format,
>    bool fail = print_it (format, fd, filename, print_stat, &pa);
>    return ! fail;
>  }
> -#endif /* USE_STATX */
>  
>  
>  /* Print stat info.  Return zero upon success, nonzero upon failure.  */
> @@ -1548,9 +1560,10 @@ print_stat (char *pformat, size_t prefix_len, unsigned 
> int m,
>        break;
>      case 'w':
>        {
> -#if ! USE_STATX
> -        btime = get_birthtime (fd, filename, statbuf);
> +#if USE_STATX
> +        if (use_stat)
>  #endif
> +          btime = get_birthtime (fd, filename, statbuf);
>          if (btime.tv_nsec < 0)
>            out_string (pformat, prefix_len, "-");
>          else
> @@ -1559,9 +1572,10 @@ print_stat (char *pformat, size_t prefix_len, unsigned 
> int m,
>        break;
>      case 'W':
>        {
> -#if ! USE_STATX
> -        btime = get_birthtime (fd, filename, statbuf);
> +#if USE_STATX
> +        if (use_stat)
>  #endif
> +          btime = get_birthtime (fd, filename, statbuf);
>          out_epoch_sec (pformat, prefix_len, neg_to_zero (btime));
>        }
>        break;
> @@ -1903,7 +1917,14 @@ main (int argc, char *argv[])
>    for (int i = optind; i < argc; i++)
>      ok &= (fs
>             ? do_statfs (argv[i], format)
> -           : do_stat (argv[i], format, format2));
> +#if USE_STATX
> +           : (use_stat
> +              ? do_stat (argv[i], format, format2)
> +              : do_statx (argv[i], format, format2))
> +#else
> +           : do_stat (argv[i], format, format2)
> +#endif
> +           );
>  
>    return ok ? EXIT_SUCCESS : EXIT_FAILURE;
>  }

-- 
Jeff Layton <jlayton@poochiereds.net>




reply via email to

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