public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v2 1/2] fstatat64: use statx on kernel using uint32 for time
@ 2021-03-19  1:18 YunQiang Su
  2021-03-19  1:18 ` [PATCH v2 2/2] MIPS: N64, make xstat as wrapper of generic fstatat YunQiang Su
  2021-03-19 18:38 ` [PATCH v2 1/2] fstatat64: use statx on kernel using uint32 for time Adhemerval Zanella
  0 siblings, 2 replies; 6+ messages in thread
From: YunQiang Su @ 2021-03-19  1:18 UTC (permalink / raw)
  To: libc-alpha
  Cc: aurelien, adhemerval.zanella, jiaxun.yang, macro, syq, YunQiang Su

MIPS N64's lagacy stat-syscalls use uint32 as its time.
Glibc converts it to int64 then. Timestamp -1 as an example:
   syscall(newfstatat) gets 0xffffffff,
   Glibc converts it to 0x00000000ffffffff
Then, -1 becomes a time in y2106.

We define a macro STAT_KERNEL64_TIME32_T for this behaviour.
fstatat also uses fstatat64_time64 internal for this case.
---
 sysdeps/unix/sysv/linux/fstatat.c          | 9 +++++++--
 sysdeps/unix/sysv/linux/fstatat64.c        | 5 ++++-
 sysdeps/unix/sysv/linux/mips/kernel_stat.h | 5 +++++
 sysdeps/unix/sysv/linux/statx_cp.h         | 4 ++++
 sysdeps/unix/sysv/linux/tst-futimens.c     | 4 ++++
 sysdeps/unix/sysv/linux/tst-utime.c        | 4 ++++
 sysdeps/unix/sysv/linux/tst-utimes.c       | 5 +++++
 7 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/fstatat.c b/sysdeps/unix/sysv/linux/fstatat.c
index 59efff615f..ccb6027b64 100644
--- a/sysdeps/unix/sysv/linux/fstatat.c
+++ b/sysdeps/unix/sysv/linux/fstatat.c
@@ -37,7 +37,12 @@ __fstatat (int fd, const char *file, struct stat *buf, int flag)
 		 || buf->__st_blocks_pad != 0))
     return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW);
 # else
-#  ifdef __NR_fstatat64
+#  if defined(STAT_KERNEL64_TIME32_T)
+   /* Some architecture, like MIPS N64, is 64bit, while its kernel_stat has 32bit timespec.
+      Since they are 64bit, and time_t is also 64bit, it is safe for this cast */
+  return __fstatat64_time64(fd, file, (struct __stat64_t64 *)buf, flag);
+#  endif
+#  if defined(__NR_fstatat64)
   /* Old KABIs with old non-LFS support, e.g. arm, i386, hppa, m68k, mips32,
      microblaze, s390, sh, powerpc, and sparc.  */
   struct stat64 st64;
@@ -72,7 +77,7 @@ __fstatat (int fd, const char *file, struct stat *buf, int flag)
       return 0;
     }
 #  else
-  /* 64-bit kabi outlier, e.g. mips64 and mips64-n32.  */
+  /* 64-bit kabi outlier, e.g. mips64-n32.  */
   struct kernel_stat kst;
   r = INTERNAL_SYSCALL_CALL (newfstatat, fd, file, &kst, flag);
   if (r == 0)
diff --git a/sysdeps/unix/sysv/linux/fstatat64.c b/sysdeps/unix/sysv/linux/fstatat64.c
index 490226a8ec..be19165f49 100644
--- a/sysdeps/unix/sysv/linux/fstatat64.c
+++ b/sysdeps/unix/sysv/linux/fstatat64.c
@@ -47,9 +47,12 @@ __fstatat64_time64 (int fd, const char *file, struct __stat64_t64 *buf,
   int r;
 
 #if (__WORDSIZE == 32 \
-     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32))
+     && (!defined __SYSCALL_WORDSIZE || __SYSCALL_WORDSIZE == 32)) \
+    || defined(STAT_KERNEL64_TIME32_T)
   /* 32-bit kABI with default 64-bit time_t, e.g. arc, riscv32.   Also
      64-bit time_t support is done through statx syscall.  */
+  /* the time_sec members of kernel_stat struct on some architecture
+     is unsigned 32bit, which has Y2106 problem. MIPS N64 is an example. */
   struct statx tmp;
   r = INTERNAL_SYSCALL_CALL (statx, fd, file, AT_NO_AUTOMOUNT | flag,
 			     STATX_BASIC_STATS, &tmp);
diff --git a/sysdeps/unix/sysv/linux/mips/kernel_stat.h b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
index e4b0f211ca..ce2e1c01ac 100644
--- a/sysdeps/unix/sysv/linux/mips/kernel_stat.h
+++ b/sysdeps/unix/sysv/linux/mips/kernel_stat.h
@@ -68,4 +68,9 @@ struct kernel_stat
 # define STATFS_IS_STATFS64 0
 #endif
 
+/* the time_sec members of kernel_stat struct is uint32_t, which has Y2106 problem */
+#if _MIPS_SIM == _ABI64
+#define STAT_KERNEL64_TIME32_T 1
+#endif
+
 #endif
diff --git a/sysdeps/unix/sysv/linux/statx_cp.h b/sysdeps/unix/sysv/linux/statx_cp.h
index 634330aaa6..cc1ae4698d 100644
--- a/sysdeps/unix/sysv/linux/statx_cp.h
+++ b/sysdeps/unix/sysv/linux/statx_cp.h
@@ -18,6 +18,10 @@
 
 extern void __cp_stat64_statx (struct stat64 *to, struct statx *from)
   attribute_hidden;
+#if defined(STAT_KERNEL64_TIME32_T)
+# define __cp_stat64_t64_statx __cp_stat64_statx
+#else
 extern void __cp_stat64_t64_statx (struct __stat64_t64 *to,
 				   const struct statx *from)
   attribute_hidden;
+#endif
diff --git a/sysdeps/unix/sysv/linux/tst-futimens.c b/sysdeps/unix/sysv/linux/tst-futimens.c
index 785cd87557..67a411db74 100644
--- a/sysdeps/unix/sysv/linux/tst-futimens.c
+++ b/sysdeps/unix/sysv/linux/tst-futimens.c
@@ -37,6 +37,9 @@ const struct timespec t2[2] = { { 0x80000001ULL, 0 },  { 0x80000002ULL, 0 } };
 /* struct timespec array around Y2038 threshold.  */
 const struct timespec t3[2] = { { 0x7FFFFFFE, 0 },  { 0x80000002ULL, 0 } };
 
+/* struct timespec array around -1: may trigger Y2106 problem */
+const struct timespec t4[2] = { { -1, 0 },  { -2, 0 } };
+
 #define PREPARE do_prepare
 static void
 do_prepare (int argc, char *argv[])
@@ -83,6 +86,7 @@ do_test (void)
   test_futimens_helper (&t1[0]);
   test_futimens_helper (&t2[0]);
   test_futimens_helper (&t3[0]);
+  test_futimens_helper (&t4[0]);
 
   return 0;
 }
diff --git a/sysdeps/unix/sysv/linux/tst-utime.c b/sysdeps/unix/sysv/linux/tst-utime.c
index 21e4e41dea..c39927fc68 100644
--- a/sysdeps/unix/sysv/linux/tst-utime.c
+++ b/sysdeps/unix/sysv/linux/tst-utime.c
@@ -39,6 +39,9 @@ const static struct utimbuf t2 = { 0x80000001ULL, 0x80000002ULL };
 /* struct utimbuf around Y2038 threshold.  */
 const static struct utimbuf t3 = { 0x7FFFFFFE, 0x80000002ULL };
 
+/* struct timespec array around -1: may trigger Y2106 problem */
+const static struct utimbuf t4 = { -1, -2 };
+
 #define PREPARE do_prepare
 static void
 do_prepare (int argc, char *argv[])
@@ -85,6 +88,7 @@ do_test (void)
   test_utime_helper (&t1);
   test_utime_helper (&t2);
   test_utime_helper (&t3);
+  test_utime_helper (&t4);
 
   return 0;
 }
diff --git a/sysdeps/unix/sysv/linux/tst-utimes.c b/sysdeps/unix/sysv/linux/tst-utimes.c
index 0f23e44897..1395aa1764 100644
--- a/sysdeps/unix/sysv/linux/tst-utimes.c
+++ b/sysdeps/unix/sysv/linux/tst-utimes.c
@@ -40,6 +40,10 @@ struct timeval t2[2] = { { 0x80000001ULL, 0 },  { 0x80000002ULL, 0 } };
 const static
 struct timeval t3[2] = { { 0x7FFFFFFE, 0 },  { 0x80000002ULL, 0 } };
 
+/* struct timespec array around -1: may trigger Y2106 problem */
+const static
+struct timeval t4[2] = { { -1, 0 },  { -2, 0 } };
+
 #define PREPARE do_prepare
 static void
 do_prepare (int argc, char *argv[])
@@ -86,6 +90,7 @@ do_test (void)
   test_utime_helper (&t1[0]);
   test_utime_helper (&t2[0]);
   test_utime_helper (&t3[0]);
+  test_utime_helper (&t4[0]);
 
   return 0;
 }
-- 
2.31.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-03-22  2:23 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-19  1:18 [PATCH v2 1/2] fstatat64: use statx on kernel using uint32 for time YunQiang Su
2021-03-19  1:18 ` [PATCH v2 2/2] MIPS: N64, make xstat as wrapper of generic fstatat YunQiang Su
2021-03-19 10:07   ` Andreas Schwab
2021-03-19 18:42   ` Adhemerval Zanella
2021-03-22  2:23     ` 回复: " yunqiang.su
2021-03-19 18:38 ` [PATCH v2 1/2] fstatat64: use statx on kernel using uint32 for time Adhemerval Zanella

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).