Commit Graph

656 Commits

Author SHA1 Message Date
Wolfgang Hommel
066f38baac Merge pull request #510 from bjornfor/fix-musl-build
Only define stat64 when building with glibc
2025-08-07 13:14:29 +02:00
Bjørn Forsman
4de86c2145 Only define stat64 when building with glibc
musl defines stat64 as stat, leading to this build error:

  gcc -o libfaketime.o -c -std=gnu99 -Wall -Wextra -Werror -DFAKE_PTHREAD -DFAKE_STAT -DFAKE_UTIME -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'/nix/store/qpyvvrcas950da98mssw6ixlw7ckvyrb-libfaketime-0.9.11'"' -DLIBDIRNAME='"'/lib'"'  -Wno-nonnull-compare   libfaketime.c
  In file included from libfaketime.c:55:
  libfaketime.c:1276:5: error: redefinition of ‘stat’
   1276 | int stat64 (const char *path, struct stat64 *buf)
        |     ^~~~~~
  /nix/store/g9cgi4yyn5vrd1f9axj8gxdvwzv5ssvk-musl-1.2.5-dev/include/sys/stat.h:80:5: note: previous definition of ‘stat’ with type ‘int(const char *, struct stat *)’
     80 | int stat(const char *__restrict, struct stat *__restrict);
        |     ^~~~
  make[1]: *** [Makefile:161: libfaketime.o] Error 1

Fix it by only defining stat64 when building against glibc, since it's
not straight forward to detect musl, and it's the safest approach; there
might be other libc implementations that behave like musl.

Fixes: 53ba71e547 ("Handle stat64() call")
2025-08-07 09:19:13 +02:00
Wolfgang Hommel
ffdb51bc30 Merge pull request #507 from bjornfor/add-stat64
Handle stat64() call
2025-08-05 20:51:42 +02:00
Wolfgang Hommel
3aa2028174 Merge pull request #509 from lisanet/master
fixes issue #506 - build arch64 and arch64e separately
2025-08-03 14:27:27 +02:00
Simone Karin Lehmann
6566162e7e fix for issue #506 - build arch64 and arch64e separately and then lipo them. 2025-08-03 13:48:41 +02:00
Bjørn Forsman
53ba71e547 Handle stat64() call
This fixes missing modification of timestamps in stat() calls for
programs built with large file support (-D_FILE_OFFSET_BITS=64), both
32- and 64-bit.

Demo code:

  $ cat <<EOF >test.c
  #include <sys/stat.h>
  int main()
  {
      struct stat buf;
      return stat("/", &buf);
  }
  EOF

32-bit build:

  $ nix-shell -p gcc --argstr system i686-linux

  nix-shell$ gcc test.c && ltrace ./a.out
  __libc_start_main([ "./a.out" ] <unfinished ...>
  stat(0x804a008, 0xffa4b644, 895, 0) = 0
  +++ exited (status 0) +++

  nix-shell$ gcc -D_FILE_OFFSET_BITS=64 test.c && ltrace ./a.out
  __libc_start_main([ "./a.out" ] <unfinished ...>
  stat64(0x804a008, 0xffdcf61c, 100, 0xffdcfaeb) = 0
  +++ exited (status 0) +++

  nix-shell$ file a.out
  a.out: ELF 32-bit LSB executable, Intel 80386, [...]

64-bit build:

  $ nix-shell -p gcc

  nix-shell$ gcc test.c && ltrace ./a.out
  stat(0x402004, 0x7ffc50a9d740, 0x7ffc50a9d908, 0x403db0) = 0
  +++ exited (status 0) +++

  nix-shell$ gcc -D_FILE_OFFSET_BITS=64 test.c && ltrace ./a.out
  stat64(0x402004, 0x7ffd5cbafba0, 0x7ffd5cbafd68, 0x403db0) = 0
  +++ exited (status 0) +++

  nix-shell$ file a.out
  a.out: ELF 64-bit LSB executable, x86-64, [...]
2025-07-09 17:32:54 +02:00
Wolfgang Hommel
6404d81f63 Merge pull request #504 from bjornfor/system-v-semaphores
Add optional System V semaphores
2025-06-27 19:33:14 +02:00
Bjørn Forsman
44c578c6d6 Add optional System V semaphore backend
By building with -DFT_SEMAPHORE_BACKEND=FT_SYSV, the System V semaphore
API is unsed instead of POSIX. This works around a glibc bug[1] and
fixes https://github.com/wolfcw/libfaketime/issues/427
("libfaketime hangs forever when 32-bit process is executed within 64-bit process").
The default backend is still POSIX, in case there are regressions in the
new code.

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=17980

Ref https://github.com/wolfcw/libfaketime/issues/427
2025-06-23 21:00:21 +02:00
Bjørn Forsman
2649cdb156 Add semaphore abstraction layer
Add ft_sem_*() functions that use the POSIX semaphore API.

In preparation for adding System V semaphores as an alternative to POSIX
semaphores, because glibc breaks POSIX semaphores when operating in
mixed 32- and 64-bit environments[1].

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=17980
2025-06-23 16:42:49 +02:00
Bjørn Forsman
71b31e908d Add missing newline to error message 2025-06-23 16:19:26 +02:00
Wolfgang Hommel
523584abd4 Merge pull request #503 from sammytranGeo/fix-monotonic-timedwait
Fix MONOTONIC pthread_cond_timedwait when REALTIME is set
2025-06-14 13:04:11 +02:00
Sammy Tran
a2e406c669 Fix MONOTONIC pthread_cond_timedwait when REALTIME is set 2025-06-13 17:13:43 -04:00
Wolfgang Hommel
3ccdd344aa Preparations for v0.9.12 release v0.9.12 2025-06-09 14:31:15 +02:00
Wolfgang Hommel
f63569e422 Merge pull request #502 from usertam/patch/fix-fake-stat64buf-on-linux
Fix fake_stat64buf() again
2025-06-09 14:26:48 +02:00
usertam
d276658b74 libfaketime.c: fix fake_stat64buf() again
I got the logic wrong in PR #501 in the inner `#ifndef __APPLE__`.
This broke building on linux. This should fix it.
2025-06-09 19:19:37 +08:00
Wolfgang Hommel
cb48e454be Merge pull request #501 from usertam/patch/clean-up-and-readme
Fix compiler warnings and update README.OSX
2025-06-09 10:24:59 +02:00
usertam
77ae25f529 README.OSX: document about the new arm64e ABI 2025-06-08 23:23:50 +08:00
usertam
30d7defcf5 libfaketime.c: get rid of stat64 things on aarch64-darwin
To give more context, stat64 is a child of large-file support (LFS)
back in 1996, during the transition from 32-bit to 64-bit. People
wanted 64-bit inodes in 32-bit systems, hence stat and stat64.

Nowadays where everything is 64-bit, stat64 is mostly just an alias
to stat, as stat is already native 64-bit. On modern implementations
like musl, stat64 is even dropped entirely as a sane default. We
observe the same in darwin's stat.h:

  #if !__DARWIN_ONLY_64_BIT_INO_T
  struct stat64 __DARWIN_STRUCT_STAT64;
  #endif /* !__DARWIN_ONLY_64_BIT_INO_T */

Because struct stat64 doesn't ever exist on aarch64-darwin, and we
don't have to worry about people using stat64 calls, we can safely
remove all stat64 bloat, according to __DARWIN_ONLY_64_BIT_INO_T.

I nuked fake_stat64buf because only STAT64_HANDLER is using it, and
only non-darwin stat64 things use that handler. I didn't do more
because people might still use stat64 things on x86_64 (on glibc)
and other older 32-bit platforms, and we still need to hook those.

A loose follow up to PR #453. Fixes the remaining clang warnings on
aarch64-darwin.
2025-06-08 19:34:48 +08:00
Wolfgang Hommel
9f7b304dbe Merge pull request #500 from usertam/patch/fix-darwin-and-arm64e
Fix darwin and arm64e
2025-06-07 23:03:01 +02:00
usertam
0277016bb5 Makefile.OSX: add -fptrauth-* flags for arm64e to work properly
Particularly we need -fptrauth-calls, so when pthread_once indirectly
calls ftpl_really_init, it won't fail PAC.
2025-06-07 20:51:07 +08:00
usertam
0e2dbe4ae1 libfaketime.c: correct macro from __APPLEOSX__ to __APPLE__
This fixes the recursive pthread_once deadlock on darwin platforms.
It looks something like this:

  Trace/BPT trap: 5

  BUG IN CLIENT OF LIBPLATFORM: Trying to recursively lock an os_once_t

The macro __APPLEOSX__ is never defined, instead __APPLE__ should be used.
This mistake inadvertently caused system_time_from_system() to always take
the linux code path on darwin, leading to recursive calls during ftpl_init().

This was exposed by PR #488 which removed the ad-hoc recursion detection
that previously masked this issue.
2025-06-07 20:51:06 +08:00
Wolfgang Hommel
45d29c8256 Merge pull request #497 from usertam/patch/compile-both-arm64-arm64e
Compile for arm64 on darwin again
2025-06-03 21:48:40 +02:00
usertam
264e8efad7 Makefile.OSX: compile a fat library of both arm64e and arm64 2025-06-01 22:50:46 +08:00
usertam
3a3d1deebc Revert "Check if the user is on ARM64, add target to CFLAGS/LDFLAGS"
This reverts commit 2a2af0fcdc.
2025-06-01 01:03:58 +08:00
Wolfgang Hommel
6714b98794 Preparations for v0.9.11 release v0.9.11 2025-05-25 10:00:14 +02:00
Wolfgang Hommel
3e56ada3ff Merge pull request #495 from PiotrBzdrega/master
missing FUTEX_CLOCK_REALTIME declaration when build with flags -DINTERCEPT_SYSCALL -DINTERCEPT_FUTEX
2025-05-24 13:03:01 +02:00
PiotrBzdrega
2dca058f5c missing FUTEX_CLOCK_REALTIME declaration when build with flags -DINTERCEPT_SYSCALL -DINTERCEPT_FUTEX 2025-05-13 15:01:47 +02:00
Wolfgang Hommel
2e2d3eefb5 Merge pull request #493 from totoroyyb/master
[DRAFT] fix: unhandled futex-related syscall
2025-03-29 11:37:26 +01:00
Yibo Yan
fa731ed50f fix: unhandled futex wait syscall 2025-03-26 21:02:47 +00:00
Wolfgang Hommel
3f6467d421 Test different Ubuntu versions 2025-01-29 17:36:42 +01:00
Wolfgang Hommel
2dac72caba Test different Ubuntu versions 2025-01-29 17:21:51 +01:00
Wolfgang Hommel
21af5175f5 pthread.h on macOS 2025-01-28 21:30:17 +01:00
Wolfgang Hommel
b5a48c870b Merge pull request #488 from ijackson/races
Fix several data races
2025-01-28 19:59:24 +01:00
Wolfgang Hommel
52fe3cc442 Merge pull request #487 from ijackson/t64
Fake 64-bit time on 32-bit systems
2025-01-28 06:26:19 +01:00
Wolfgang Hommel
63aef51102 Merge pull request #486 from ijackson/utime
Re-disable faking utime by default
2025-01-28 06:24:32 +01:00
Ian Jackson
50e2c56914 Don't use _try_ locking calls for monotonic_conds_lock
This reverts commit 8ef74e33b6
   "Swapped out pthread_rwlock_xxlock() ..."

This could result in concurrent uses of pthread_cond_* erroneously
returning EAGAIN, which is not permitted by the spec and which the
application way well treat as a bug.  This seems to be happening in
gem2deb in ci.debian.net.

The commit message in 8ef74e33b6 says (rewrapped)

    Swapped out pthread_rwlock_xxlock(), which doesn't return if it
    can't obtain the lock, with pthread_rwlock_xxtrylock() followed by
    sched yield and error code return. The issue is sometimes a thread
    calling pthread_cond_init() or pthread_cond_destroy() can't
    acquire the lock when another thread is waiting on a condition
    variable notification via pthread_cond_timedwait(), and thus the
    thread calling pthread_cond_init() or pthread_cond_destroy() end
    up hanging indefinitely.

I don't think this is true.  The things that are done with
monotonic_conds_lock held are HASH_ADD_PTR HASH_FIND_PTR etc. on
monotonic_conds, which should all be fast and AFAICT don't in turn
take any locks.  So it shouldn't deadlock.

I conjecture that the underlying bug being experienced by the author
of "Swapped out pthread_rwlock_xxlock" was the lack of ftpl_init - ie,
access to an uninitialised pthread_rwlock_t.  That might result in a
hang.
2025-01-27 13:12:45 +00:00
Ian Jackson
b6e87c6f26 Call ftpl_init before using monotonic_conds_lock
Otherwise we can use this in an uninitialised state, which is not
allowed.

We call ftpl_init in pthread_cond_init_232, but the application might
not have called that.  For example, it might have a static condition
variable set up with PTHREAD_COND_INITIALIZER.
2025-01-27 13:12:45 +00:00
Ian Jackson
d9ba684b18 Replace data race with use of pthread_once (ft_shm_init) 2025-01-27 13:12:45 +00:00
Ian Jackson
2503b0fffc Replace data race with use of pthread_once (ftpl_init)
At the cost of no longer nicely detecting recursive initialisation
problems.

Fixes Debian bug #1093599
2025-01-27 13:12:38 +00:00
Ian Jackson
97721e5491 Interpose gettimeofday64 2025-01-27 12:27:03 +00:00
Ian Jackson
fdb5ba3f7a Interpose __time64 2025-01-27 12:27:03 +00:00
Ian Jackson
f289bf702f Fix interposition of clock_gettime64
timespec.tv_nsec is 32-bit, even though timeval.tv_usec is
64-bit (weirdly).  This doesn't matter very much in practice because
 * on little endian architectures (which is all our 32-bit release
   arches) writing to a too big integer ends up writing the
   desired value in the desired location, and
 * it doesn't affect the overall struct size on any of our actual
   architectures (which align the uint64_t to 8 so must make the
   whole struct 16 not 12), so the write overflow is harmless.

> #include <time.h>
> #include <sys/time.h>
> #include <stdio.h>
> struct timeval tv;
> struct timespec ts;
> int main(void) {
>    printf("time_t %lld\n", (unsigned long long) sizeof(time_t));
>    printf("timeval %lld %lld %lld\n",
>           (unsigned long long) sizeof(tv),
>           (unsigned long long) sizeof(tv.tv_sec),
>           (unsigned long long) sizeof(tv.tv_usec)
>           );
>    printf("timespec %lld %lld %lld\n",
>           (unsigned long long) sizeof(ts),
>           (unsigned long long) sizeof(ts.tv_sec),
>           (unsigned long long) sizeof(ts.tv_nsec)
>           );
> }
> (sid_armhf-dchroot)iwj@amdahl:~/Faketime/test$ gcc t.c
> (sid_armhf-dchroot)iwj@amdahl:~/Faketime/test$ ./a.out
> time_t 8
> timeval 16 8 8
> timespec 16 8 4
> (sid_armhf-dchroot)iwj@amdahl:~/Faketime/test$
2025-01-27 12:27:03 +00:00
Helge Deller
536889d797 Interpose clock_gettime64
Since debian generally added 64-bit time support on 32-bit
arches, now glibc sometimes calls the clock_gettime64 syscall
(and library wrapper).  This function was missing, and is added here.

Patch originally supplied here
  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1064555
2025-01-27 12:26:40 +00:00
Ian Jackson
19b2476534 Re-disable faking utime by default
Fixes
  https://github.com/wolfcw/libfaketime/issues/483

See also
  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1093412#35
Hopefully this will fix Debian #1093412.
2025-01-27 12:22:48 +00:00
Wolfgang Hommel
92c322507c Merge pull request #485 from LocutusOfBorg/master
test/libmallocintercept.c: fix write function unused return value
2025-01-25 13:04:34 +01:00
Gianfranco Costamagna
0516055224 test/libmallocintercept.c: fix write function unused return value
We should ignore the return value for logging function, to fix a new gcc ftbfs
libmallocintercept.c: In function ‘print_msg’:
libmallocintercept.c:27:9: error: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Werror=unused-result]
   27 |         write(0, msg, strlen(msg));
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
2025-01-22 12:22:37 +01:00
Wolfgang Hommel
ba9ed5b289 Merge pull request #473 from EgnalZurc/patch-1
Preventing shared semaphore to be used again
2024-06-05 19:52:44 +02:00
Egnal Zurc
7e9d69b98f Preventing shared sem to be used again
The shared semaphore is closed but it's not assigned to null.
That's required because the logic check the semaphore status if it's not null. For this reason, we are getting a core some times.
2024-06-05 12:16:41 +02:00
Wolfgang Hommel
a04750217b ft_dlvsym() check for NULL version 2024-03-24 21:08:36 +01:00
Wolfgang Hommel
a3e91605ad Merge pull request #463 from Rob--W/issue-130-dlsym
Add FAKETIME_IGNORE_SYMBOLS to skip unneeded dlsym
2024-03-19 19:43:22 +01:00