Commit Graph

659 Commits

Author SHA1 Message Date
Bjørn Forsman
cccce3bf23 Replace #!/bin/bash shebangs with #!/usr/bin/env bash
For portability. E.g. /bin/bash doesn't exist on NixOS.
2025-09-24 15:02:44 +02:00
Wolfgang Hommel
4fc06b90df Merge pull request #512 from sammytranGeo/correct-use-of-real-monotonic-clock
Use real clock monotonic when not faking
2025-08-23 19:33:26 +02:00
Sammy Tran
75e130c4f1 Use real clock monotonic when not faking 2025-08-13 15:15:12 -04:00
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