Skip to content

Commit

Permalink
Fix "Add __{,f,l}stat{,at}_time64 weak aliases" once again
Browse files Browse the repository at this point in the history
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 b10f732.

[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
  • Loading branch information
gportay committed Nov 12, 2023
1 parent cf58e68 commit 3919157
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 16 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
68 changes: 68 additions & 0 deletions __fstat64_time64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2023 Gaël PORTAY
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

#ifdef __linux__
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <dlfcn.h>
#include <sys/xattr.h>
#include <fcntl.h>

#include <sys/stat.h>

#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
77 changes: 77 additions & 0 deletions __fstatat64_time64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright 2023 Gaël PORTAY
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

#ifdef __linux__
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <limits.h>
#include <dlfcn.h>
#include <sys/xattr.h>

#include <fcntl.h>
#include <sys/stat.h>

#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
32 changes: 32 additions & 0 deletions __lstat64_time64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2023 Gaël PORTAY
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

#ifdef __linux__
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>

#include <sys/stat.h>

#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
31 changes: 31 additions & 0 deletions __stat64_time64.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2023 Gaël PORTAY
*
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

#ifdef __linux__
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>

#include <sys/stat.h>

#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
2 changes: 0 additions & 2 deletions fstat64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 0 additions & 4 deletions fstatat64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 0 additions & 4 deletions lstat64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 0 additions & 4 deletions stat64.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
2 changes: 0 additions & 2 deletions support/i686-archlinux32-rootfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.

0 comments on commit 3919157

Please sign in to comment.