summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Hommel <wolfgang.hommel@unibw.de>2022-02-16 21:27:08 +0100
committerWolfgang Hommel <wolfgang.hommel@unibw.de>2022-02-16 21:27:08 +0100
commitee4f57d8a581fe2fb826d820954eecc0c33e8724 (patch)
tree77124b66383d6ee4b75002ef959b67a60fe63806
parent5466cd8a5f0c892828a96430cea2a3fc0c1e0ae2 (diff)
downloadlibfaketime-ee4f57d8a581fe2fb826d820954eecc0c33e8724.tar.gz
Additional dyld interposing for macOS Monterey support (addresses #357)
-rw-r--r--src/Makefile.OSX20
-rw-r--r--src/libfaketime.c57
2 files changed, 72 insertions, 5 deletions
diff --git a/src/Makefile.OSX b/src/Makefile.OSX
index ee9efde..d5f4c88 100644
--- a/src/Makefile.OSX
+++ b/src/Makefile.OSX
@@ -18,8 +18,22 @@
# without this, but the performance impact may require you to
# try it unsynchronized.
#
-# FAKE_SLEEP
-# - Also intercept sleep(), nanosleep(), usleep(), alarm(), [p]poll()
+# FAKE_SLEEP
+# - Also intercept sleep(), nanosleep(), usleep(), alarm(), [p]poll()
+#
+# MACOS_DYLD_INTERPOSE
+# - Use dlyd interposing instead of name-based function interception
+# (required since macOS Monterey)
+#
+# FAKE_RANDOM
+# - Intercept getentropy(). Dangerous for production use.
+# See README about FAKE_RANDOM.
+#
+# FAKE_SETTIME
+# - Intercept clock_settime(), settimeofday(), and adjtime()
+#
+# FAKE_PID
+# - Enable faked values for getpid() calls through FAKETIME_FAKEPID
#
# * Compilation addition: second libMT target added for building the pthread-
# enabled library as a separate library
@@ -38,7 +52,7 @@ INSTALL ?= install
PREFIX ?= /usr/local
-CFLAGS += -DFAKE_SLEEP -DFAKE_INTERNAL_CALLS -DPREFIX='"'${PREFIX}'"' $(FAKETIME_COMPILE_CFLAGS) -DMACOS_DYLD_INTERPOSE
+CFLAGS += -DFAKE_SLEEP -DFAKE_INTERNAL_CALLS -DPREFIX='"'${PREFIX}'"' $(FAKETIME_COMPILE_CFLAGS) -DMACOS_DYLD_INTERPOSE -DFAKE_SETTIME
LIB_LDFLAGS += -dynamiclib -current_version 0.9.9 -compatibility_version 0.7
SONAME = 1
diff --git a/src/libfaketime.c b/src/libfaketime.c
index 2583370..228b766 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -3802,7 +3802,11 @@ __asm__(".symver pthread_cond_destroy_232, pthread_cond_destroy@@GLIBC_2.3.2");
* Based on suggestion and prototype by @ojura, see https://github.com/wolfcw/libfaketime/issues/179
*/
#ifdef FAKE_SETTIME
+#ifdef MACOS_DYLD_INTERPOSE
+int macos_clock_settime(clockid_t clk_id, const struct timespec *tp) {
+#else
int clock_settime(clockid_t clk_id, const struct timespec *tp) {
+#endif
/* only CLOCK_REALTIME can be set */
if (clk_id != CLOCK_REALTIME) {
@@ -3820,7 +3824,11 @@ int clock_settime(clockid_t clk_id, const struct timespec *tp) {
we do not have to care about 'x' or 'i' modifiers given previously,
as they are not erased when parsing them. */
struct timespec current_time;
+#ifdef MACOS_DYLD_INTERPOSE
+ DONT_FAKE_TIME(macos_clock_gettime(clk_id, &current_time))
+#else
DONT_FAKE_TIME(clock_gettime(clk_id, &current_time))
+#endif
;
time_t sec_diff = tp->tv_sec - current_time.tv_sec;
@@ -3873,7 +3881,11 @@ int clock_settime(clockid_t clk_id, const struct timespec *tp) {
return 0;
}
+#ifdef MACOS_DYLD_INTERPOSE
+int macos_settimeofday(const struct timeval *tv, void *tz)
+#else
int settimeofday(const struct timeval *tv, void *tz)
+#endif
{
/* The use of timezone *tz is obsolete and simply ignored here. */
if (tz == NULL) tz = NULL;
@@ -3888,12 +3900,20 @@ int settimeofday(const struct timeval *tv, void *tz)
struct timespec tp;
tp.tv_sec = tv->tv_sec;
tp.tv_nsec = tv->tv_usec * 1000;
+#ifdef MACOS_DYLD_INTERPOSE
+ macos_clock_settime(CLOCK_REALTIME, &tp);
+#else
clock_settime(CLOCK_REALTIME, &tp);
+#endif
}
return 0;
}
+#ifdef MACOS_DYLD_INTERPOSE
+int macos_adjtime (const struct timeval *delta, struct timeval *olddelta)
+#else
int adjtime (const struct timeval *delta, struct timeval *olddelta)
+#endif
{
/* Always signal true full success when olddelta is requested. */
if (olddelta != NULL)
@@ -3905,14 +3925,22 @@ int adjtime (const struct timeval *delta, struct timeval *olddelta)
if (delta != NULL)
{
struct timespec tp;
+#ifdef MACOS_DYLD_INTERPOSE
+ macos_clock_gettime(CLOCK_REALTIME, &tp);
+#else
clock_gettime(CLOCK_REALTIME, &tp);
+#endif
tp.tv_sec += delta->tv_sec;
tp.tv_nsec += delta->tv_usec * 1000;
/* This actually will make the clock jump instead of gradually
adjusting it, but we fulfill the caller's intention and an
additional thread just for the gradual changes does not seem
to be worth the effort presently. */
+#ifdef MACOS_DYLD_INTERPOSE
clock_settime(CLOCK_REALTIME, &tp);
+#else
+ clock_settime(CLOCK_REALTIME, &tp);
+#endif
}
return 0;
}
@@ -3960,19 +3988,31 @@ ssize_t getrandom(void *buf, size_t buflen, unsigned int flags) {
return real_getrandom(buf, buflen, flags);
}
}
+#ifdef MACOS_DYLD_INTERPOSE
+int macos_getentropy(void *buffer, size_t length) {
+#else
int getentropy(void *buffer, size_t length) {
+#endif
if (bypass_randomness(buffer, length)) {
return 0;
} else {
if (!initialized)
ftpl_init();
+#ifdef MACOS_DYLD_INTERPOSE
+ return getentropy(buffer, length);
+#else
return real_getentropy(buffer, length);
+#endif
}
}
#endif
#ifdef FAKE_PID
+#ifdef MACOS_DYLD_INTERPOSE
+pid_t macos_getpid() {
+#else
pid_t getpid() {
+#endif
const char *pidstring = getenv("FAKETIME_FAKEPID");
if (pidstring != NULL) {
long int pid = strtol(pidstring, NULL, 0);
@@ -4026,17 +4066,30 @@ long syscall(long number, ...) {
#ifdef MACOS_DYLD_INTERPOSE
void do_macos_dyld_interpose(void) {
- DYLD_INTERPOSE(macos_alarm, alarm);
DYLD_INTERPOSE(macos_clock_gettime, clock_gettime);
DYLD_INTERPOSE(macos_gettimeofday, gettimeofday);
DYLD_INTERPOSE(macos_time, time);
DYLD_INTERPOSE(macos_ftime, ftime);
+#ifdef FAKE_SLEEP
+ DYLD_INTERPOSE(macos_alarm, alarm);
DYLD_INTERPOSE(macos_sleep, sleep);
DYLD_INTERPOSE(macos_usleep, usleep);
DYLD_INTERPOSE(macos_nanosleep, nanosleep);
DYLD_INTERPOSE(macos_poll, poll);
- DYLD_INTERPOSE(macos_select, select);
+#endif
DYLD_INTERPOSE(macos_timespec_get, timespec_get);
+ DYLD_INTERPOSE(macos_select, select);
+#ifdef FAKE_RANDOM
+ DYLD_INTERPOSE(macos_getentropy, getentropy);
+#endif
+#ifdef FAKE_SETTIME
+ DYLD_INTERPOSE(macos_clock_settime, clock_settime);
+ DYLD_INTERPOSE(macos_settimeofday, settimeofday);
+ DYLD_INTERPOSE(macos_adjtime, adjtime);
+#endif
+#ifdef FAKE_PID
+ DYLD_INTERPOSE(macos_getpid, getpid);
+#endif
}
#endif