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