Skip to content

Commit cb48e45

Browse files
authored
Merge pull request #501 from usertam/patch/clean-up-and-readme
Fix compiler warnings and update README.OSX
2 parents 9f7b304 + 77ae25f commit cb48e45

File tree

2 files changed

+55
-16
lines changed

2 files changed

+55
-16
lines changed

README.OSX

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,3 +166,50 @@ The environment variable FAKETIME can be changed at application run-time
166166
and always takes precedence over other user-controlled settings. It can
167167
be re-set to 0 (zero) to work around potential incompatibilities or if
168168
you do not want libfaketime applied to your software.
169+
170+
5) Working with the new arm64e system binaries in Apple Silicon
171+
---------------------------------------------------------------
172+
173+
Since Apple Silicon, Apple started shipping system binaries compiled against
174+
the `arm64e` ABI. This new ABI enforces Pointer Authentication Codes (PACs),
175+
and enforces assembly instructions to sign and check pointer signatures to
176+
prevent malicious control flow altering.
177+
178+
$ file /bin/date
179+
/bin/date: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
180+
/bin/date (for architecture x86_64): Mach-O 64-bit executable x86_64
181+
/bin/date (for architecture arm64e): Mach-O 64-bit executable arm64e
182+
183+
Most importantly, the new `arm64e` ABI is incompatible with the normal `arm64`
184+
ABI we are used to; this is done so that everything `arm64e` is PAC-enforced.
185+
186+
As a result, this will happen when we try to hook naive `arm64` libfaketime on
187+
system binaries (and vice versa with `arm64e` libfaketime on `arm64` binaries):
188+
189+
$ DYLD_INSERT_LIBRARIES=libfaketime.1.dylib /bin/date
190+
dyld[5788]: terminating because inserted dylib 'libfaketime.1.dylib' could not be loaded:
191+
tried: 'libfaketime.1.dylib' (mach-o file, but is an incompatible architecture (have 'arm64', need 'arm64e'))
192+
193+
Since PR #497, we now compile libfaketime with a fat library/binary setup, so
194+
that we support both ABIs at the same time:
195+
196+
$ file libfaketime.1.dylib
197+
libfaketime.1.dylib: Mach-O universal binary with 2 architectures: [arm64:Mach-O 64-bit dynamically linked shared library arm64] [arm64e:Mach-O 64-bit dynamically linked shared library arm64e]
198+
libfaketime.1.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
199+
libfaketime.1.dylib (for architecture arm64e): Mach-O 64-bit dynamically linked shared library arm64e
200+
201+
Unfortunately, Apple does not support running third-party `arm64e` code yet,
202+
since the ABI is still unstable. This means that you cannot use libfaketime
203+
on system `arm64e` binaries out of the box, at the time of writing.
204+
205+
If you really need to, you may disable SIP in the recovery terminal:
206+
207+
(in recovery) # csrutil disable
208+
209+
And enable the experimental ABI after boot:
210+
211+
(in regular boot) $ sudo nvram boot-args=-arm64e_preview_abi
212+
213+
Then `arm64e` should work as-is. This use case is rather uncommon since most
214+
userspace binaries will remain `arm64` for the time being, until Apple really
215+
doubles down on `arm64e`. Regardless, we should be prepared for that.

src/libfaketime.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -208,10 +208,12 @@ static int (*real_xstat) (int, const char *, struct stat *);
208208
static int (*real_fxstat) (int, int, struct stat *);
209209
static int (*real_fxstatat) (int, int, const char *, struct stat *, int);
210210
static int (*real_lxstat) (int, const char *, struct stat *);
211+
#if !defined(__APPLE__) || !__DARWIN_ONLY_64_BIT_INO_T
211212
static int (*real_xstat64) (int, const char *, struct stat64 *);
212213
static int (*real_fxstat64) (int, int , struct stat64 *);
213214
static int (*real_fxstatat64) (int, int , const char *, struct stat64 *, int);
214215
static int (*real_lxstat64) (int, const char *, struct stat64 *);
216+
#endif
215217
#ifdef STATX_TYPE
216218
static int (*real_statx) (int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf);
217219
#endif
@@ -983,6 +985,7 @@ static inline void fake_statbuf (struct stat *buf) {
983985
#endif
984986
}
985987

988+
#ifndef __APPLE__
986989
static inline void fake_stat64buf (struct stat64 *buf) {
987990
#ifndef st_atime
988991
lock_for_stat();
@@ -992,18 +995,13 @@ static inline void fake_stat64buf (struct stat64 *buf) {
992995
unlock_for_stat();
993996
#else
994997
lock_for_stat();
995-
#ifndef __APPLE__
996-
fake_clock_gettime(CLOCK_REALTIME, &buf->st_ctim);
997-
fake_clock_gettime(CLOCK_REALTIME, &buf->st_atim);
998-
fake_clock_gettime(CLOCK_REALTIME, &buf->st_mtim);
999-
#else
1000998
fake_clock_gettime(CLOCK_REALTIME, &buf->st_ctimespec);
1001999
fake_clock_gettime(CLOCK_REALTIME, &buf->st_atimespec);
10021000
fake_clock_gettime(CLOCK_REALTIME, &buf->st_mtimespec);
1003-
#endif
10041001
unlock_for_stat();
10051002
#endif
10061003
}
1004+
#endif
10071005

10081006
/* macOS dyld interposing uses the function's real name instead of real_name */
10091007
#ifdef MACOS_DYLD_INTERPOSE
@@ -1113,42 +1111,34 @@ int __lxstat (int ver, const char *path, struct stat *buf)
11131111
{
11141112
STAT_HANDLER(lxstat, buf, ver, path, buf);
11151113
}
1116-
#endif
11171114

1118-
#ifndef __APPLE__
11191115
/* Contributed by Philipp Hachtmann in version 0.6 */
11201116
int __xstat64 (int ver, const char *path, struct stat64 *buf)
11211117
{
11221118
STAT64_HANDLER(xstat64, buf, ver, path, buf);
11231119
}
1124-
#endif
11251120

1126-
#ifndef __APPLE__
11271121
/* Contributed by Philipp Hachtmann in version 0.6 */
11281122
int __fxstat64 (int ver, int fildes, struct stat64 *buf)
11291123
{
11301124
STAT64_HANDLER(fxstat64, buf, ver, fildes, buf);
11311125
}
1132-
#endif
11331126

1134-
#ifndef __APPLE__
11351127
/* Added in v0.8 as suggested by Daniel Kahn Gillmor */
11361128
#ifndef NO_ATFILE
11371129
int __fxstatat64 (int ver, int fildes, const char *filename, struct stat64 *buf, int flag)
11381130
{
11391131
STAT64_HANDLER(fxstatat64, buf, ver, fildes, filename, buf, flag);
11401132
}
11411133
#endif
1142-
#endif
11431134

1144-
#ifndef __APPLE__
11451135
/* Contributed by Philipp Hachtmann in version 0.6 */
11461136
int __lxstat64 (int ver, const char *path, struct stat64 *buf)
11471137
{
11481138
STAT64_HANDLER(lxstat64, buf, ver, path, buf);
11491139
}
1150-
#endif
1151-
#endif
1140+
#endif /* ifndef __APPLE__ */
1141+
#endif /* ifdef FAKE_STAT */
11521142

11531143
#ifdef STATX_TYPE
11541144
static inline void fake_statx_timestamp(struct statx_timestamp* p)
@@ -2689,10 +2679,12 @@ static void ftpl_really_init(void)
26892679
real_fxstat = dlsym(RTLD_NEXT, "__fxstat");
26902680
real_fxstatat = dlsym(RTLD_NEXT, "__fxstatat");
26912681
real_lxstat = dlsym(RTLD_NEXT, "__lxstat");
2682+
#if !defined(__APPLE__) || !__DARWIN_ONLY_64_BIT_INO_T
26922683
real_xstat64 = dlsym(RTLD_NEXT,"__xstat64");
26932684
real_fxstat64 = dlsym(RTLD_NEXT, "__fxstat64");
26942685
real_fxstatat64 = dlsym(RTLD_NEXT, "__fxstatat64");
26952686
real_lxstat64 = dlsym(RTLD_NEXT, "__lxstat64");
2687+
#endif
26962688
#ifdef STATX_TYPE
26972689
real_statx = dlsym(RTLD_NEXT, "statx");
26982690
#endif

0 commit comments

Comments
 (0)