From aa03f722f3b994aaf81e72a8904bf33196780930 Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Mon, 20 Jul 2020 16:02:04 -0300 Subject: linux: Add {f}stat{at} y2038 support A new struct __stat{64}_t64 type is added with the required __timespec64 time definition. Only LFS is added, 64-bit time with 32-bit offsets is not supposed to be supported (no existing glibc configuration supports such a combination). It is done with an extra __NR_statx call plus a conversion to the new __stat{64}_t64 type. The statx call is done only for 32-bit time_t ABIs. Internally some extra routines to copy from/to struct stat{64} to struct __stat{64} used on multiple implementations (stat, fstat, lstat, and fstatat) are added on a extra implementation (stat_t64_cp.c). Alse some extra routines to copy from statx to __stat{64} is added on statx_cp.c. Checked with a build for all affected ABIs. I also checked on x86_64, i686, powerpc, powerpc64le, sparcv9, sparc64, s390, and s390x. Reviewed-by: Lukasz Majewski --- sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h | 17 ++++++----------- sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c | 3 --- 2 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c (limited to 'sysdeps/unix/sysv/linux/mips') diff --git a/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h b/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h index 7f226416f9..1805d4b85f 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h +++ b/sysdeps/unix/sysv/linux/mips/mips64/kstat_cp.h @@ -22,11 +22,14 @@ static inline int __cp_kstat_stat (const struct kernel_stat *kst, struct stat *st) { + if (! in_ino_t_range (kst->st_ino) + || ! in_off_t_range (kst->st_size) + || ! in_blkcnt_t_range (kst->st_blocks)) + return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW); + st->st_dev = kst->st_dev; memset (&st->st_pad1, 0, sizeof (st->st_pad1)); st->st_ino = kst->st_ino; - if (st->st_ino != kst->st_ino) - return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW); st->st_mode = kst->st_mode; st->st_nlink = kst->st_nlink; st->st_uid = kst->st_uid; @@ -34,8 +37,6 @@ __cp_kstat_stat (const struct kernel_stat *kst, struct stat *st) st->st_rdev = kst->st_rdev; memset (&st->st_pad2, 0, sizeof (st->st_pad2)); st->st_size = kst->st_size; - if (st->st_size != kst->st_size) - return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW); st->st_pad3 = 0; st->st_atim.tv_sec = kst->st_atime_sec; st->st_atim.tv_nsec = kst->st_atime_nsec; @@ -45,26 +46,21 @@ __cp_kstat_stat (const struct kernel_stat *kst, struct stat *st) st->st_ctim.tv_nsec = kst->st_ctime_nsec; st->st_blksize = kst->st_blksize; st->st_blocks = kst->st_blocks; - if (st->st_blocks != kst->st_blocks) - return INLINE_SYSCALL_ERROR_RETURN_VALUE (EOVERFLOW); memset (&st->st_pad5, 0, sizeof (st->st_pad5)); return 0; } static inline int -__cp_kstat_stat64 (const struct kernel_stat *kst, struct stat64 *st) +__cp_kstat_stat64_t64 (const struct kernel_stat *kst, struct __stat64_t64 *st) { st->st_dev = kst->st_dev; - memset (&st->st_pad1, 0, sizeof (st->st_pad1)); st->st_ino = kst->st_ino; st->st_mode = kst->st_mode; st->st_nlink = kst->st_nlink; st->st_uid = kst->st_uid; st->st_gid = kst->st_gid; st->st_rdev = kst->st_rdev; - memset (&st->st_pad2, 0, sizeof (st->st_pad2)); - st->st_pad3 = 0; st->st_size = kst->st_size; st->st_blksize = kst->st_blksize; st->st_blocks = kst->st_blocks; @@ -74,7 +70,6 @@ __cp_kstat_stat64 (const struct kernel_stat *kst, struct stat64 *st) st->st_mtim.tv_nsec = kst->st_mtime_nsec; st->st_ctim.tv_sec = kst->st_ctime_sec; st->st_ctim.tv_nsec = kst->st_ctime_nsec; - memset (&st->st_pad4, 0, sizeof (st->st_pad4)); return 0; } diff --git a/sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c b/sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c deleted file mode 100644 index 260cda987e..0000000000 --- a/sysdeps/unix/sysv/linux/mips/mips64/statx_cp.c +++ /dev/null @@ -1,3 +0,0 @@ -/* Override the generic statx_cp.c which is only needed for new 32-bit arch - without stat64 family support. - */ -- cgit 1.4.1