Repository navigation
Intercept lstat64, fstat64, fstatat and fstatat64 (glibc >= 2.33) - #565
Merged
Merged
Conversation
Since glibc 2.33, the stat family is exported from libc as regular functions, and programs built against it call fstatat(), fstatat64(), fstat64() and lstat64() directly instead of going through the __fxstatat*() / __fxstat64() / __lxstat64() wrappers. libfaketime only hooked the old wrappers for these, so with FAKE_STAT the times they return were not faked. Python's os.scandir() / DirEntry.stat() and os.stat(dir_fd=...) are common examples. Add wrappers for the four functions next to stat64(), using the existing STAT_HANDLER / STAT64_HANDLER, and a functional test that checks every stat entry point reports the faked mtime. Fixes wolfcw#477
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #477.
Since glibc 2.33,
fstatat,fstatat64,fstat64andlstat64are exported from libc as regular functions (@@GLIBC_2.33), and programs built against a newer glibc call them directly rather than going through__fxstatat,__fxstatat64,__fxstat64and__lxstat64. libfaketime only intercepts the__*xstat*wrappers for these, so withFAKE_STATthey return real file times whilestat()returns faked ones. Python is one common case:os.scandir()/DirEntry.stat()usefstatat, and so doesos.stat(..., dir_fd=...).This PR adds wrappers for the four functions next to the existing
stat64()wrapper. They use the sameSTAT_HANDLER/STAT64_HANDLERmacros and the same__GLIBC__/_TIME_BITS != 64guards, with thefstatat*pair also underNO_ATFILE. The real functions are looked up withdlsym(RTLD_NEXT, ...)like the others. On glibc < 2.33 these symbols are not exported by libc (programs get them fromlibc_nonshared.a, which calls the__*xstat*functions), so behaviour there does not change.It also adds
test/stat_entry_points_test.candtest/functests/test_stat_entry_points.sh. The test sets a file's mtime and checks thatstat,lstat,fstatand, on glibc,fstatat,stat64,lstat64,fstat64andfstatat64all report the faked mtime underFAKETIME=+1d.Reproducer
The reproducer from #477, extended to the other three functions:
With
touch -d '2020-01-01 00:00:00 UTC' 1andFAKETIME=-1d LD_PRELOAD=src/libfaketime.so.1:Python:
Testing
make testpasses on Ubuntu 24.04 (glibc 2.39) and Debian 13 (glibc 2.41), on both x86_64 and aarch64. The new test fails against master's library on all four, forfstatat,lstat64,fstat64andfstatat64.test/docker_baseline.sh alpine:3.20(musl) passes. The glibc-only checks are skipped there.test/release_check.shandtest/compile_abi_variants.sh(gcc and clang) pass, a clang build passes the new test, and the macOS build (Makefile.OSX) still compiles.