[PATCH] linux: Fix fstatat with !XSTAT_IS_XSTAT64 and __TIMESIZE=64 (BZ #29730)
Aurelien Jarno
aurelien@aurel32.net
Tue Nov 1 21:31:50 GMT 2022
On 2022-11-01 09:40, Adhemerval Zanella Netto via Libc-alpha wrote:
>
>
> On 01/11/22 08:57, Aurelien Jarno wrote:
> > On 2022-11-01 11:55, Aurelien Jarno wrote:
> >> On 2022-10-31 23:20, Aurelien Jarno wrote:
> >>> On 2022-10-31 14:25, Adhemerval Zanella Netto via Libc-alpha wrote:
> >>>>
> >>>>
> >>>> On 31/10/22 13:03, Adhemerval Zanella Netto wrote:
> >>>>>
> >>>>>
> >>>>> On 28/10/22 17:54, Aurelien Jarno wrote:
> >>>>>> Commit 6e8a0aac2f883 ("time: Fix overflow itimer tests on 32-bit
> >>>>>> systems") changed in_time_t_range to assume a 32-bit time_t. Therefore
> >>>>>> stop calling it from __fstatat for systems with 64-bit time_t.
> >>>>>>
> >>>>>> Resolves: BZ #29730
> >>>>>
> >>>>> Although this change is not incorrect, I think the fix I just sent [1] is
> >>>>> slight better because it just alias non-LFS stat to LFS stat for mips
> >>>>> (which is also a small runtime and code optimization), while avoiding
> >>>>> touching generic code (so we need to check if trigger another issue on
> >>>>> different architecture).
> >>>>>
> >>>>> [1] https://sourceware.org/pipermail/libc-alpha/2022-October/143089.html
> >>>>
> >>>> So I was wrong that we can assume stat and stat64 are equal on mips. Maybe
> >>>> instead of adding the fix on stat we can make it more generic and move it
> >>>> to is_time_t_range (so it can potentially fix usage not only on stat code)
> >>>> as my comment on https://sourceware.org/bugzilla/show_bug.cgi?id=29730 ?
> >>>
> >>> Yes, we can move it to is_time_t_range, but then it gets trickier to get
> >>> the condition. Your comment in BZ #29730 uses TIME64_NON_DEFAULT, but it
> >>> is not defined for OpenRISC, so it means it will cast to time_t. However
> >>> this has been explicitly changed that way in commit 6e8a0aac2f883 to
> >>> unbreak OpenRISC.
> >>>
> >>> We probably want a condition that is "kernel ABI uses 32-bit time_t". Do
> >>> we have something like that already defined?
> >>
> >> I guess this can be checked with:
> >> (__WORDSIZE == 32 && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
> >>
> >> And then we can rename the function to is_ktime_t_range to better
> >> reflect its behaviour.
> >
> > Looking at it more in details, I am not sure it's a good idea, as this
> > function is also used for non-syscall cases, like in mktime or timegm.
> > While that works because there is a __TIMESIZE != 64 guard, this still
> > seems fragile.
>
> The "(__WORDSIZE == 32 && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))"
> is a Linuxism and I agree it should not be used in generic code.
>
> >
> > In that regard, I think the approach from YunQiang to explicitly call
> > either one or the other function might be better.
> >
> > An hybrid solution would be to define both in_time_t_range and
> > in_ktime_t_range, the later being the one called in_int32_t_range in
> > YunQiang's patch.
> >
> > What do you think?
> >
>
> I am more inclined to either go with your initial patch that handles it on
> fstatat or go with a mips specific fstatat.c to make clear about MIPS ABI
> idiosyncrasies (which is something I tried to avoid, but for this specific
> case seems to make sense):
>
> * sysdeps/unix/sysv/linux/mips/mips64/n64/fstatat.c:
>
> /* Different than other ABIS, mips64 has different layouts for non-LFS
> and LFS struct stat. */
> int
> __fstatat (int fd, const char *file, struct stat *buf, int flag)
> {
> struct __stat64_t64 st64;
> int r = __fstatat64_time64 (fd, file, &st64, flag);
> if (r == 0)
> {
> /* Clear internal pad and reserved fields. */
> memset (buf, 0, sizeof (*buf));
>
> buf->st_dev = st64.st_dev;
> buf->st_ino = st64.st_ino;
> buf->st_mode = st64.st_mode;
> buf->st_nlink = st64.st_nlink;
> buf->st_uid = st64.st_uid;
> buf->st_gid = st64.st_gid;
> buf->st_rdev = st64.st_rdev;
> buf->st_size = st64.st_size;
> buf->st_blksize = st64.st_blksize;
> buf->st_blocks = st64.st_blocks;
> buf->st_atim = st64.st_atim;
> buf->st_mtim = st64.st_mtim;
> buf->st_ctim = st64.st_ctim;
> }
> return r;
> }
>
> We can then treat the YunQiang patch as a code refactor instead.
Sounds good. I have tested that solution and confirm it works fine. I
have just sent a proper patch for that.
--
Aurelien Jarno GPG: 4096R/1DDD8C9B
aurelien@aurel32.net http://www.aurel32.net
More information about the Libc-alpha
mailing list