Re: [PATCH] stat: fix negative %X/%Y/%Z timestamps after Y2038 on 32-bit builds

Denys Vlasenko via busybox <[email protected]>
Newsgroups gmane.linux.busybox
Message-ID <CAK1hOcOJn+qxyBO12+_1jQ860H6LAW4nq0CwFt2e9O4C-JogUw@mail.gmail.com>
Applied, thank you.

On Sat, Aug 22, 2026 at 5:33 PM Benjamin Robin via busybox
<[email protected]> wrote:
>
> Introduce a utility function to always print `time_t` values using either
> `long long` or `unsigned long long`, depending on whether `time_t` is
> signed. This fixes the bug reported in [1].
>
> Previously, `time_t` values were cast to `long`, which is a 32-bit value
> on 32-bit builds.
>
> [1]: https://lists.busybox.net/pipermail/busybox/2026-August/092413.html
>
> Signed-off-by: Benjamin Robin <[email protected]>
> ---
>  coreutils/stat.c | 26 +++++++++++++++++---------
>  1 file changed, 17 insertions(+), 9 deletions(-)
>
> diff --git a/coreutils/stat.c b/coreutils/stat.c
> index 2c2909e7e45b..e504ab1ab7f2 100644
> --- a/coreutils/stat.c
> +++ b/coreutils/stat.c
> @@ -303,12 +303,25 @@ static void FAST_FUNC print_statfs(char *pformat, const char m,
>  }
>  #endif
>
> +static void FAST_FUNC print_time_t(char *pformat, time_t val)
> +{
> +#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
> +
> +       if (TYPE_SIGNED(time_t)) {
> +               strcat(pformat, "lld");
> +               printf(pformat, (long long) val);
> +       }
> +       else {
> +               strcat(pformat, "llu");
> +               printf(pformat, (unsigned long long) val);
> +       }
> +}
> +
>  /* print stat info */
>  static void FAST_FUNC print_stat(char *pformat, const char m,
>                 const char *const filename, const void *data
>                 IF_SELINUX(, security_context_t scontext))
>  {
> -#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
>         struct stat *statbuf = (struct stat *) data;
>         struct passwd *pw_ent;
>         struct group *gw_ent;
> @@ -382,20 +395,15 @@ static void FAST_FUNC print_stat(char *pformat, const char m,
>         } else if (m == 'x') {
>                 printfs(pformat, human_time(&statbuf->st_atim));
>         } else if (m == 'X') {
> -               strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu");
> -               /* note: (unsigned long) would be wrong:
> -                * imagine (unsigned long64)int32 */
> -               printf(pformat, (long) statbuf->st_atime);
> +               print_time_t(pformat, statbuf->st_atime);
>         } else if (m == 'y') {
>                 printfs(pformat, human_time(&statbuf->st_mtim));
>         } else if (m == 'Y') {
> -               strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu");
> -               printf(pformat, (long) statbuf->st_mtime);
> +               print_time_t(pformat, statbuf->st_mtime);
>         } else if (m == 'z') {
>                 printfs(pformat, human_time(&statbuf->st_ctim));
>         } else if (m == 'Z') {
> -               strcat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu");
> -               printf(pformat, (long) statbuf->st_ctime);
> +               print_time_t(pformat, statbuf->st_ctime);
>  # if ENABLE_SELINUX
>         } else if (m == 'C' && (option_mask32 & OPT_SELINUX)) {
>                 printfs(pformat, scontext);
>
> ---
> base-commit: 7473045ad3504db9b421427a452fd9b146346306
> change-id: 20260822-fix-stat-seconds-since-epoch-b80c5eb17371
>
> Best regards,
> --
> Benjamin Robin <[email protected]>
>
> _______________________________________________
> busybox mailing list
> [email protected]
> https://lists.busybox.net/mailman/listinfo/busybox
_______________________________________________
busybox mailing list
[email protected]
https://lists.busybox.net/mailman/listinfo/busybox
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.