From 391915733359bdcc8751233f2bc0652f2ddd5b9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABl=20PORTAY?= Date: Mon, 9 Oct 2023 17:11:56 +0200 Subject: [PATCH] Fix "Add __{,f,l}stat{,at}_time64 weak aliases" once again The 64-bit time stat symbols were introduced with glibc-2.33 to prepare the glibc for y2038[1] (aka Epochalypse, 03:14:07 UTC on 19 January 2038, i.e. 32-bit time overlow to Epoch, 00:00:00 UTC on 1 January 1970). First for LFS[2] (Large File Support, i.e. 64-bit time definition on 64-bit offset), then for legacy ABI[3]. It appears these symbols are used on the 32-bit architectures x86 and arm (eabi, hf); and they are not used on the 64-bit architectures x86_64, aarch64 and riscv64 (lp64). This removes the weak aliases and implements the functions if the timesize is 32-bits. This fixes commit b10f732dfecd5b318a9d427b9af1a5d309ab41fd. [1]: https://sourceware.org/git/?p=glibc.git;a=commit;h=aa03f722f3b994aaf81e72a8904bf33196780930 [2]: https://sourceware.org/git/?p=glibc.git;a=commit;h=47f24c21ee38701ae275aa9e451f70fa3e77478c [3]: https://www.gnu.org/software/gnulib/manual/html_node/Avoiding-the-year-2038-problem.html --- CHANGELOG.md | 8 +++ Makefile | 4 ++ __fstat64_time64.c | 68 +++++++++++++++++++++++++ __fstatat64_time64.c | 77 +++++++++++++++++++++++++++++ __lstat64_time64.c | 32 ++++++++++++ __stat64_time64.c | 31 ++++++++++++ fstat64.c | 2 - fstatat64.c | 4 -- lstat64.c | 4 -- stat64.c | 4 -- support/i686-archlinux32-rootfs.txt | 2 - 11 files changed, 220 insertions(+), 16 deletions(-) create mode 100644 __fstat64_time64.c create mode 100644 __fstatat64_time64.c create mode 100644 __lstat64_time64.c create mode 100644 __stat64_time64.c diff --git a/CHANGELOG.md b/CHANGELOG.md index bc270a79..658f767c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## [unreleased] + +### Fixed + +- Fix the interception of the `_time64` variant functions `__fstat64_time64()`, + `__fstatat64_time64()`, `__lstat64_time64()` and `__stat64_time64()` on + 32-bit architectures ([glibc] on x86, ARM and ARM hard-float) + ## [v13] - 2023-10-11 ### Added diff --git a/Makefile b/Makefile index 93fecbf9..2eacbcc9 100644 --- a/Makefile +++ b/Makefile @@ -76,17 +76,21 @@ endif all: libiamroot.so libiamroot.so: __abort.o +libiamroot.so: __fstat64_time64.o +libiamroot.so: __fstatat64_time64.o libiamroot.so: __fxstat.o libiamroot.so: __fxstat64.o libiamroot.so: __fxstatat.o libiamroot.so: __fxstatat64.o libiamroot.so: __libc_start_main.o +libiamroot.so: __lstat64_time64.o libiamroot.so: __lxstat.o libiamroot.so: __lxstat64.o libiamroot.so: __open_2.o libiamroot.so: __openat_2.o libiamroot.so: __opendir2.o libiamroot.so: __pathdlperror.o +libiamroot.so: __stat64_time64.o libiamroot.so: __verbosef.o libiamroot.so: __xmknod.o libiamroot.so: __xmknodat.o diff --git a/__fstat64_time64.c b/__fstat64_time64.c new file mode 100644 index 00000000..74ffd563 --- /dev/null +++ b/__fstat64_time64.c @@ -0,0 +1,68 @@ +/* + * Copyright 2023 Gaël PORTAY + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifdef __linux__ +#include +#include +#include +#include +#include +#include + +#include + +#include "iamroot.h" + +#ifdef __GLIBC__ +#ifdef _LARGEFILE64_SOURCE +#if __TIMESIZE == 32 +static int (*sym)(int, struct stat64 *); + +__attribute__((visibility("hidden"))) +int next___fstat64_time64(int fd, struct stat64 *statbuf) +{ + if (!sym) + sym = dlsym(RTLD_NEXT, "__fstat64_time64"); + + if (!sym) + return __dl_set_errno_and_perror(ENOSYS, -1); + + return sym(fd, statbuf); +} + +int __fstat64_time64(int fd, struct stat64 *statbuf) +{ + uid_t uid; + gid_t gid; + int ret; + + ret = next___fstat64_time64(fd, statbuf); + if (ret == -1) + goto exit; + + uid = __fget_uid(fd); + if (uid == (uid_t)-1) + statbuf->st_uid = 0; + + gid = __fget_gid(fd); + if (gid == (gid_t)-1) + statbuf->st_gid = 0; + + __fst_mode(fd, statbuf); + __fst_uid(fd, statbuf); + __fst_gid(fd, statbuf); + +exit: + __debug("%s(fd: %i <-> '%s', ...) -> %i\n", __func__, fd, __fpath(fd), + ret); + + return ret; +} + +#endif +#endif +#endif +#endif diff --git a/__fstatat64_time64.c b/__fstatat64_time64.c new file mode 100644 index 00000000..aab32182 --- /dev/null +++ b/__fstatat64_time64.c @@ -0,0 +1,77 @@ +/* + * Copyright 2023 Gaël PORTAY + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifdef __linux__ +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "iamroot.h" + +#ifdef __GLIBC__ +#ifdef _LARGEFILE64_SOURCE +#if __TIMESIZE == 32 +static int (*sym)(int, const char *, struct stat64 *, int); + +__attribute__((visibility("hidden"))) +int next___fstatat64_time64(int dfd, const char *path, struct stat64 *statbuf, + int atflags) +{ + if (!sym) + sym = dlsym(RTLD_NEXT, "__fstatat64_time64"); + + if (!sym) + return __dl_set_errno_and_perror(ENOSYS, -1); + + return sym(dfd, path, statbuf, atflags); +} + +int __fstatat64_time64(int dfd, const char *path, struct stat64 *statbuf, + int atflags) +{ + char buf[PATH_MAX]; + int ret = -1; + ssize_t siz; + uid_t uid; + gid_t gid; + + siz = path_resolution(dfd, path, buf, sizeof(buf), atflags); + if (siz == -1) + goto exit; + + ret = next___fstatat64_time64(dfd, buf, statbuf, atflags); + if (ret == -1) + goto exit; + + uid = __get_uid(buf); + if (uid == (uid_t)-1) + statbuf->st_uid = 0; + + gid = __get_gid(buf); + if (gid == (gid_t)-1) + statbuf->st_gid = 0; + + __st_mode(buf, statbuf); + __st_uid(buf, statbuf); + __st_gid(buf, statbuf); + +exit: + __debug("%s(dfd: %i <-> '%s', path: '%s' -> '%s', ..., atflags: 0x%x) -> %i\n", + __func__, dfd, __fpath(dfd), path, buf, atflags, ret); + + return ret; +} + +#endif +#endif +#endif +#endif diff --git a/__lstat64_time64.c b/__lstat64_time64.c new file mode 100644 index 00000000..0cacd135 --- /dev/null +++ b/__lstat64_time64.c @@ -0,0 +1,32 @@ +/* + * Copyright 2023 Gaël PORTAY + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifdef __linux__ +#include +#include +#include + +#include + +#include "iamroot.h" + +#ifdef __GLIBC__ +#ifdef _LARGEFILE64_SOURCE +#if __TIMESIZE == 32 +extern int __fstatat64_time64(int, const char *, struct stat64 *, int); + +int __lstat64_time64(const char *path, struct stat64 *statbuf) +{ + __debug("%s(path: '%s', ...)\n", __func__, path); + + /* Forward to another function */ + return __fstatat64_time64(AT_FDCWD, path, statbuf, + AT_SYMLINK_NOFOLLOW); +} +#endif +#endif +#endif +#endif diff --git a/__stat64_time64.c b/__stat64_time64.c new file mode 100644 index 00000000..1445f050 --- /dev/null +++ b/__stat64_time64.c @@ -0,0 +1,31 @@ +/* + * Copyright 2023 Gaël PORTAY + * + * SPDX-License-Identifier: LGPL-2.1-or-later + */ + +#ifdef __linux__ +#include +#include +#include + +#include + +#include "iamroot.h" + +#ifdef __GLIBC__ +#ifdef _LARGEFILE64_SOURCE +#if __TIMESIZE == 32 +extern int __fstatat64_time64(int, const char *, struct stat64 *, int); + +int __stat64_time64(const char *path, struct stat64 *statbuf) +{ + __debug("%s(path: '%s', ...)\n", __func__, path); + + /* Forward to another function */ + return __fstatat64_time64(AT_FDCWD, path, statbuf, 0); +} +#endif +#endif +#endif +#endif diff --git a/fstat64.c b/fstat64.c index 35738d00..779263d0 100644 --- a/fstat64.c +++ b/fstat64.c @@ -68,7 +68,5 @@ int fstat64(int fd, struct stat64 *statbuf) int __fstat64 (int __fd, struct stat64 *__buf) __THROW __nonnull ((2)); weak_alias(fstat64, __fstat64); -int __fstat64_time64 (int __fd, struct stat64 *__buf) __THROW __nonnull ((2)); -weak_alias(fstat64, __fstat64_time64); #endif #endif diff --git a/fstatat64.c b/fstatat64.c index cbd3f31e..ccffb0c2 100644 --- a/fstatat64.c +++ b/fstatat64.c @@ -79,9 +79,5 @@ int __fstatat64 (int __fd, const char *__restrict __file, struct stat64 *__restrict __buf, int __flag) __THROW __nonnull ((2, 3)); weak_alias(fstatat64, __fstatat64); -int __fstatat64_time64 (int __fd, const char *__restrict __file, - struct stat64 *__restrict __buf, int __flag) - __THROW __nonnull ((2, 3)); -weak_alias(fstatat64, __fstatat64_time64); #endif #endif diff --git a/lstat64.c b/lstat64.c index 1c4c473a..bfa0c620 100644 --- a/lstat64.c +++ b/lstat64.c @@ -26,9 +26,5 @@ int __lstat64 (const char *__restrict __file, struct stat64 *__restrict __buf) __THROW __nonnull ((1, 2)); weak_alias(lstat64, __lstat64); -int __lstat64_time64 (const char *__restrict __file, - struct stat64 *__restrict __buf) - __THROW __nonnull ((1, 2)); -weak_alias(lstat64, __lstat64_time64); #endif #endif diff --git a/stat64.c b/stat64.c index 0e15523d..8fec77fa 100644 --- a/stat64.c +++ b/stat64.c @@ -25,9 +25,5 @@ int stat64(const char *path, struct stat64 *statbuf) int __stat64 (const char *__restrict __file, struct stat64 *__restrict __buf) __THROW __nonnull ((1, 2)); weak_alias(stat64, __stat64); -int __stat64_time64 (const char *__restrict __file, - struct stat64 *__restrict __buf) - __THROW __nonnull ((1, 2)); -weak_alias(stat64, __stat64_time64); #endif #endif diff --git a/support/i686-archlinux32-rootfs.txt b/support/i686-archlinux32-rootfs.txt index 5bfcb638..6de362bb 100644 --- a/support/i686-archlinux32-rootfs.txt +++ b/support/i686-archlinux32-rootfs.txt @@ -285,7 +285,5 @@ Warning: chmod: /dev/vhost-vsock: Ignoring error 'Operation not permitted'! Skipped: Running in chroot. (XXX/XXX) Arming ConditionNeedsUpdate... (XXX/XXX) Rebuilding certificate stores... -find: File system loop detected; '/etc/ssl/certs/java' is part of the same file system loop as '/etc/ssl/certs'. -error: command failed to execute correctly (XXX/XXX) Reloading system bus configuration... Skipped: Running in chroot.