Update to 0.9.10 (+ backports)

This commit is contained in:
Pablo Greco 2022-01-26 21:06:31 -03:00
parent d704b3f4dc
commit 3f10aecd40
9 changed files with 962 additions and 73 deletions

2
.gitignore vendored
View File

@ -1,2 +1,4 @@
/libfaketime-0.9.6.tar.gz
/libfaketime-0.9.8.tar.xz
/libfaketime-0.9.9.tar.gz
/libfaketime-0.9.10.tar.gz

View File

@ -0,0 +1,27 @@
From eaa86dbed279351c845f5ed9525595ee9714b166 Mon Sep 17 00:00:00 2001
From: Pablo Greco <pgreco@centosproject.org>
Date: Tue, 10 May 2022 12:29:40 -0300
Subject: [PATCH] Disable unused-result-warning in tests
---
test/libmallocintercept.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/test/libmallocintercept.c b/test/libmallocintercept.c
index e789d34..103eac2 100644
--- a/test/libmallocintercept.c
+++ b/test/libmallocintercept.c
@@ -24,7 +24,10 @@
#include <unistd.h>
static void print_msg(const char *msg) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-result"
write(0, msg, strlen(msg));
+#pragma GCC diagnostic pop
}
static void* actual_malloc(size_t size) {
--
2.36.1

View File

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Pablo Greco <pgreco@centosproject.org>
Date: Sun, 5 Jun 2022 05:33:35 -0300
Subject: [PATCH] Fix gettimeofday aarch64/epel8
---
src/libfaketime.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libfaketime.c b/src/libfaketime.c
index 2272fab..d2900ee 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -2237,7 +2237,7 @@ int ftime(struct timeb *tb)
#ifdef MACOS_DYLD_INTERPOSE
int macos_gettimeofday(struct timeval *tv, void *tz)
#else
-int gettimeofday(struct timeval *tv, void *tz)
+int gettimeofday(struct timeval *__restrict tv, __timezone_ptr_t tz)
#endif
{
int result;
--
2.36.1

View File

@ -1,26 +0,0 @@
From 108370f850e5efd18f4989370cdc6ea6a2f74206 Mon Sep 17 00:00:00 2001
From: Wolfgang Hommel <wolfgang.hommel@unibw.de>
Date: Thu, 29 Aug 2019 09:55:04 +0200
Subject: [PATCH] Adds FORCE_PTHREAD_NONVER flag for platforms where pthread
functions are not intercepted
---
src/libfaketime.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libfaketime.c b/src/libfaketime.c
index 5e7ebdf..b70a3d3 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -3157,7 +3157,7 @@ int pthread_cond_timedwait_232(pthread_cond_t *cond, pthread_mutex_t *mutex, con
}
__asm__(".symver pthread_cond_timedwait_225, pthread_cond_timedwait@GLIBC_2.2.5");
-#ifdef __ARM_ARCH
+#if defined __ARM_ARCH || defined FORCE_PTHREAD_NONVER
__asm__(".symver pthread_cond_timedwait_232, pthread_cond_timedwait@@");
__asm__(".symver pthread_cond_init_232, pthread_cond_init@@");
__asm__(".symver pthread_cond_destroy_232, pthread_cond_destroy@@");
--
2.21.0

874
libfaketime-backports.patch Normal file
View File

@ -0,0 +1,874 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Hommel <wolfgang.hommel@unibw.de>
Date: Fri, 4 Mar 2022 20:33:18 +0100
Subject: [PATCH 01/16] Update NEWS file about v0.9.10 changes
---
NEWS | 2 ++
1 file changed, 2 insertions(+)
diff --git a/NEWS b/NEWS
index 2ed3d44..e6bbc0a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,6 @@
Since 0.9.9:
+ - automatically try to decide about FORCE_MONOTONIC_FIX
+ at run-time when not set as a compile-time flag
- improved macOS Monterey support through dyld interposing
- changed interception hooks for stat() and similar functions,
refactored to use a common handler (@sirainen)
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ian Norton <ian.norton@ncipher.com>
Date: Fri, 18 Mar 2022 12:03:24 +0000
Subject: [PATCH 02/16] fixes #374 fix compiling without FAKE_STAT
---
src/libfaketime.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/src/libfaketime.c b/src/libfaketime.c
index e632395..0c28e5f 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -830,6 +830,10 @@ static bool load_time(struct timespec *tp)
* Faked system functions: file related === FAKE(FILE)
* =======================================================================
*/
+#ifdef FAKE_UTIME
+static int fake_utime_disabled = 0;
+#endif
+
#ifdef FAKE_STAT
@@ -843,7 +847,6 @@ static bool load_time(struct timespec *tp)
#include <sys/stat.h>
static int fake_stat_disabled = 0;
-static int fake_utime_disabled = 1;
static bool user_per_tick_inc_set_backup = false;
void lock_for_stat()
@@ -2699,9 +2702,8 @@ static void ftpl_init(void)
}
#endif
#if defined FAKE_FILE_TIMESTAMPS
-#ifndef FAKE_UTIME
- fake_utime_disabled = 0; // Defaults to enabled w/o FAKE_UTIME define
-#endif
+#ifdef FAKE_UTIME
+ // fake_utime_disabled is 0 by default
if ((tmp_env = getenv("FAKE_UTIME")) != NULL) //Note that this is NOT re-checked
{
if (!*tmp_env || *tmp_env == 'y' || *tmp_env == 'Y' || *tmp_env == 't' || *tmp_env == 'T')
@@ -2713,6 +2715,10 @@ static void ftpl_init(void)
fake_utime_disabled = !atoi(tmp_env);
}
}
+#else
+ // compiled without FAKE_UTIME support, so don't allow it to be controlled by the env var
+ fake_utime_disabled = 1;
+#endif
#endif
if ((tmp_env = getenv("FAKETIME_CACHE_DURATION")) != NULL)
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Hommel <wolf@code-wizards.com>
Date: Sat, 2 Apr 2022 13:47:04 +0200
Subject: [PATCH 03/16] select(): Scale timeout parameter by user rate on
return (addresses #382)
---
src/libfaketime.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/src/libfaketime.c b/src/libfaketime.c
index 0c28e5f..684f153 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -1725,6 +1725,21 @@ int select(int nfds, fd_set *readfds,
#else
DONT_FAKE_TIME(ret = (*real_select)(nfds, readfds, writefds, errorfds, timeout == NULL ? timeout : &timeout_real));
#endif
+
+ /* scale timeout back if user rate is set, #382 */
+ if (user_rate_set && (timeout != NULL))
+ {
+ struct timespec ts;
+
+ ts.tv_sec = timeout_real.tv_sec;
+ ts.tv_nsec = timeout_real.tv_usec * 1000;
+
+ timespecmul(&ts, user_rate, &ts);
+
+ timeout->tv_sec = ts.tv_sec;
+ timeout->tv_usec = ts.tv_nsec / 1000;
+ }
+
return ret;
}
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Hommel <wolf@code-wizards.com>
Date: Sat, 2 Apr 2022 13:52:18 +0200
Subject: [PATCH 04/16] Honor tv_nsec in timeouts on ppoll() calls (addresses
#381)
---
src/libfaketime.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/libfaketime.c b/src/libfaketime.c
index 684f153..f92ecf8 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -1567,7 +1567,7 @@ int ppoll(struct pollfd *fds, nfds_t nfds,
}
if (timeout_ts != NULL)
{
- if (user_rate_set && !dont_fake && (timeout_ts->tv_sec > 0))
+ if (user_rate_set && !dont_fake && ((timeout_ts->tv_sec > 0) || (timeout_ts->tv_nsec > 0)))
{
timespecmul(timeout_ts, 1.0 / user_rate, &real_timeout);
real_timeout_pt = &real_timeout;
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Date: Sat, 16 Apr 2022 10:05:40 -0700
Subject: [PATCH 05/16] tests: clean whitespace in Makefile
---
test/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/Makefile b/test/Makefile
index 1b2a4aa..0a76a66 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -7,7 +7,7 @@ SRC = timetest.c
OBJ = ${SRC:.c=.o}
TEST_SNIPPETS = $(notdir $(basename $(wildcard snippets/*.c)))
-EXPECTATIONS= $(notdir $(basename $(wildcard snippets/*.variable)))
+EXPECTATIONS = $(notdir $(basename $(wildcard snippets/*.variable)))
ALL_TESTS = timetest test
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Date: Sat, 16 Apr 2022 10:06:23 -0700
Subject: [PATCH 06/16] tests: avoid testing syscall snippets if
-DINTERCEPT_SYSCALL is not set
See https://bugs.debian.org/1007828
---
test/Makefile | 3 +++
1 file changed, 3 insertions(+)
diff --git a/test/Makefile b/test/Makefile
index 0a76a66..bc6f400 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -13,6 +13,9 @@ ALL_TESTS = timetest test
ifneq ($(filter -DINTERCEPT_SYSCALL,${CFLAGS}),)
ALL_TESTS += confirm_variadic_promotion
+else
+TEST_SNIPPETS := $(filter-out syscall%,${TEST_SNIPPETS})
+EXPECTATIONS := $(filter-out syscall%,${EXPECTATIONS})
endif
all: $(ALL_TESTS)
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Daniel Kahn Gillmor <dkg@fifthhorseman.net>
Date: Sat, 16 Apr 2022 10:27:53 -0700
Subject: [PATCH 07/16] test: remember to clean up repeat_random
---
test/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/Makefile b/test/Makefile
index 1b2a4aa..f7803fc 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -70,7 +70,7 @@ use_lib_%: _use_lib_test.c snippets/%.c lib%.so
## cleanup and metainformation
clean:
- @rm -f ${OBJ} timetest getrandom_test syscall_test $(foreach f,${TEST_SNIPPETS},use_lib_${f} lib${f}.so run_${f}) variadic_promotion variadic/*.o
+ @rm -f ${OBJ} timetest getrandom_test syscall_test $(foreach f,${TEST_SNIPPETS},use_lib_${f} lib${f}.so run_${f}) variadic_promotion variadic/*.o repeat_random
distclean: clean
@echo
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Uli Schlachter <psychon@znc.in>
Date: Wed, 4 May 2022 14:25:13 +0200
Subject: [PATCH 08/16] Add test reproducing ASAN-like hangs
Backtraces suggest that AddressSanitizer replaces malloc() with a
function that
- locks a mutex and
- calls clock_gettime() while the mutex is held
This commit adds a test that implements a trivial malloc() that behaves
similarly. Currently, this test hangs.
Signed-off-by: Uli Schlachter <psychon@znc.in>
---
test/Makefile | 5 ++-
test/libmallocintercept.c | 79 +++++++++++++++++++++++++++++++++++++++
test/test.sh | 9 +++++
3 files changed, 92 insertions(+), 1 deletion(-)
create mode 100644 test/libmallocintercept.c
diff --git a/test/Makefile b/test/Makefile
index afdc594..a019c45 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -26,7 +26,7 @@ all: $(ALL_TESTS)
timetest: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
-test: timetest functest
+test: timetest functest libmallocintercept.so
@echo
@./test.sh
@@ -40,6 +40,9 @@ functest:
randomtest: repeat_random
./randomtest.sh
+libmallocintercept.so: libmallocintercept.c
+ ${CC} -shared -o $@ -fpic ${CFLAGS} $<
+
# ensure our variadic argument unpacking/repacking works as expected
confirm_variadic_promotion: variadic_promotion
./variadic_promotion
diff --git a/test/libmallocintercept.c b/test/libmallocintercept.c
new file mode 100644
index 0000000..363ea95
--- /dev/null
+++ b/test/libmallocintercept.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2022 be.storaged GmbH
+ *
+ * This file is part of libfaketime
+ *
+ * libfaketime is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License v2 as published by the
+ * Free Software Foundation.
+ *
+ * libfaketime is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License v2 along
+ * with the libfaketime; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static void print_msg(const char *msg) {
+ write(0, msg, strlen(msg));
+}
+
+static void* actual_malloc(size_t size) {
+ /* We would like to use "the real malloc", but cannot. Thus, this
+ * implements a trivial, allocate-only bump allocator to make things
+ * work.
+ */
+ static char memory_arena[16 << 20];
+ static size_t allocated_index = 0;
+
+ void *result = &memory_arena[allocated_index];
+
+ allocated_index += size;
+ /* align to a multiple of 8 bytes */
+ allocated_index = (allocated_index + 7) / 8 * 8;
+
+ if (allocated_index >= sizeof(memory_arena)) {
+ print_msg("libmallocintercept is out of memory!");
+ abort();
+ }
+
+ return result;
+}
+
+static void poke_faketime(void) {
+ /* To complicate things for libfaketime, this calls clock_gettime()
+ * while holding a lock. This should simulate problems that occurred
+ * with address sanitizer.
+ */
+ static pthread_mutex_t time_mutex = PTHREAD_MUTEX_INITIALIZER;
+ struct timespec timespec;
+
+ pthread_mutex_lock(&time_mutex);
+ clock_gettime(CLOCK_REALTIME, &timespec);
+ pthread_mutex_unlock(&time_mutex);
+}
+
+void *malloc(size_t size) {
+ print_msg("Called malloc() from libmallocintercept...");
+ poke_faketime();
+ print_msg("successfully\n");
+ return actual_malloc(size);
+}
+
+void free(void *) {
+ print_msg("Called free() from libmallocintercept...");
+ poke_faketime();
+ print_msg("successfully\n");
+
+ /* We cannot actually free memory */
+}
+
diff --git a/test/test.sh b/test/test.sh
index 35f2a52..1ef7439 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -1,6 +1,7 @@
#!/bin/sh
FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
+MALLOC_INTERCEPT=./libmallocintercept.so
if [ -f /etc/faketimerc ] ; then
echo "Running the test program with your system-wide default in /etc/faketimerc"
@@ -62,6 +63,14 @@ echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"-15d\" date"
LD_PRELOAD="$FTPL" FAKETIME="-15d" date
echo
+echo "============================================================================="
+echo
+
+echo "Running the test program with malloc interception"
+echo "\$ LD_PRELOAD=./libmallocintercept.so:$FTPL ./timetest"
+LD_PRELOAD="./libmallocintercept.so:$FTPL" ./timetest
+echo
+
echo "============================================================================="
echo "Testing finished."
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Uli Schlachter <psychon@znc.in>
Date: Wed, 4 May 2022 14:51:35 +0200
Subject: [PATCH 09/16] Add FAIL_PRE_INIT_CALLS define
This commit adds a new define FAIL_PRE_INIT_CALLS. When that define is
set, calls to clock_gettime() that occur before ftpl_init() was called
(due to being marked with __attribute__((constructor))) will just fail
and return -1.
After this commit, the test case added in the previous commit no longer
hangs. To make this actually work, this new define is enabled by
default.
Fixes: https://github.com/wolfcw/libfaketime/issues/365
Signed-off-by: Uli Schlachter <psychon@znc.in>
---
src/Makefile | 7 ++++++-
src/libfaketime.c | 11 +++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/Makefile b/src/Makefile
index 62e924c..df72d47 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -27,6 +27,11 @@
# without this, but the performance impact may require you to
# try it unsynchronized.
#
+# FAIL_PRE_INIT_CALLS
+# - If the time is queried before the library was initialised, let the
+# call fail instead of trying to initialise on-the-fly. This fixes /
+# works around hangs that were seen with address sanitizer.
+#
# * Compilation Defines that are unset by default:
#
# FAKE_FILE_TIMESTAMPS, FAKE_UTIME
@@ -110,7 +115,7 @@ PREFIX ?= /usr/local
LIBDIRNAME ?= /lib/faketime
PLATFORM ?=$(shell uname)
-CFLAGS += -std=gnu99 -Wall -Wextra -Werror -Wno-nonnull-compare -DFAKE_PTHREAD -DFAKE_STAT -DFAKE_UTIME -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'$(PREFIX)'"' -DLIBDIRNAME='"'$(LIBDIRNAME)'"' $(FAKETIME_COMPILE_CFLAGS)
+CFLAGS += -std=gnu99 -Wall -Wextra -Werror -Wno-nonnull-compare -DFAKE_PTHREAD -DFAKE_STAT -DFAKE_UTIME -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -DFAIL_PRE_INIT_CALLS -fPIC -DPREFIX='"'$(PREFIX)'"' -DLIBDIRNAME='"'$(LIBDIRNAME)'"' $(FAKETIME_COMPILE_CFLAGS)
ifeq ($(PLATFORM),SunOS)
CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
endif
diff --git a/src/libfaketime.c b/src/libfaketime.c
index f92ecf8..ec80ec8 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -2282,6 +2282,16 @@ int clock_gettime(clockid_t clk_id, struct timespec *tp)
if (!initialized)
{
recursion_depth++;
+#ifdef FAIL_PRE_INIT_CALLS
+ fprintf(stderr, "libfaketime: clock_gettime() was called before initialization.\n");
+ fprintf(stderr, "libfaketime: Returning -1 on clock_gettime().\n");
+ if (tp != NULL)
+ {
+ tp->tv_sec = 0;
+ tp->tv_nsec = 0;
+ }
+ return -1;
+#else
if (recursion_depth == 2)
{
fprintf(stderr, "libfaketime: Unexpected recursive calls to clock_gettime() without proper initialization. Trying alternative.\n");
@@ -2302,6 +2312,7 @@ int clock_gettime(clockid_t clk_id, struct timespec *tp)
else {
ftpl_init();
}
+#endif
recursion_depth--;
}
/* sanity check */
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Uli Schlachter <psychon@znc.in>
Date: Sun, 8 May 2022 19:17:27 +0200
Subject: [PATCH 10/16] Disable FAILRE_PRE_INIT_CALLS by default
Signed-off-by: Uli Schlachter <psychon@znc.in>
---
src/Makefile | 12 ++++++------
test/libmallocintercept.c | 4 ++++
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/Makefile b/src/Makefile
index df72d47..6ece674 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -27,11 +27,6 @@
# without this, but the performance impact may require you to
# try it unsynchronized.
#
-# FAIL_PRE_INIT_CALLS
-# - If the time is queried before the library was initialised, let the
-# call fail instead of trying to initialise on-the-fly. This fixes /
-# works around hangs that were seen with address sanitizer.
-#
# * Compilation Defines that are unset by default:
#
# FAKE_FILE_TIMESTAMPS, FAKE_UTIME
@@ -89,6 +84,11 @@
# - avoid that the faketime wrapper complains when running within a
# libfaketime environment
#
+# FAIL_PRE_INIT_CALLS
+# - If the time is queried before the library was initialised, let the
+# call fail instead of trying to initialise on-the-fly. This fixes /
+# works around hangs that were seen with address sanitizer.
+#
# * Compilation addition: second libMT target added for building the pthread-
# enabled library as a separate library
#
@@ -115,7 +115,7 @@ PREFIX ?= /usr/local
LIBDIRNAME ?= /lib/faketime
PLATFORM ?=$(shell uname)
-CFLAGS += -std=gnu99 -Wall -Wextra -Werror -Wno-nonnull-compare -DFAKE_PTHREAD -DFAKE_STAT -DFAKE_UTIME -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -DFAIL_PRE_INIT_CALLS -fPIC -DPREFIX='"'$(PREFIX)'"' -DLIBDIRNAME='"'$(LIBDIRNAME)'"' $(FAKETIME_COMPILE_CFLAGS)
+CFLAGS += -std=gnu99 -Wall -Wextra -Werror -Wno-nonnull-compare -DFAKE_PTHREAD -DFAKE_STAT -DFAKE_UTIME -DFAKE_SLEEP -DFAKE_TIMERS -DFAKE_INTERNAL_CALLS -fPIC -DPREFIX='"'$(PREFIX)'"' -DLIBDIRNAME='"'$(LIBDIRNAME)'"' $(FAKETIME_COMPILE_CFLAGS)
ifeq ($(PLATFORM),SunOS)
CFLAGS += -D__EXTENSIONS__ -D_XOPEN_SOURCE=600
endif
diff --git a/test/libmallocintercept.c b/test/libmallocintercept.c
index 363ea95..5ed0f67 100644
--- a/test/libmallocintercept.c
+++ b/test/libmallocintercept.c
@@ -50,6 +50,7 @@ static void* actual_malloc(size_t size) {
}
static void poke_faketime(void) {
+#ifdef FAIL_PRE_INIT_CALLS
/* To complicate things for libfaketime, this calls clock_gettime()
* while holding a lock. This should simulate problems that occurred
* with address sanitizer.
@@ -60,6 +61,9 @@ static void poke_faketime(void) {
pthread_mutex_lock(&time_mutex);
clock_gettime(CLOCK_REALTIME, &timespec);
pthread_mutex_unlock(&time_mutex);
+#else
+ print_msg("FAIL_PRE_INIT_CALLS not defined, skipping poke_faketime() ");
+#endif
}
void *malloc(size_t size) {
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Uli Schlachter <psychon@znc.in>
Date: Sun, 8 May 2022 19:20:51 +0200
Subject: [PATCH 11/16] Add libmallocintercept.so to make clean
Signed-off-by: Uli Schlachter <psychon@znc.in>
---
test/Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/Makefile b/test/Makefile
index a019c45..763ebc4 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -76,7 +76,7 @@ use_lib_%: _use_lib_test.c snippets/%.c lib%.so
## cleanup and metainformation
clean:
- @rm -f ${OBJ} timetest getrandom_test syscall_test $(foreach f,${TEST_SNIPPETS},use_lib_${f} lib${f}.so run_${f}) variadic_promotion variadic/*.o repeat_random
+ @rm -f ${OBJ} timetest getrandom_test syscall_test $(foreach f,${TEST_SNIPPETS},use_lib_${f} lib${f}.so run_${f}) variadic_promotion variadic/*.o repeat_random libmallocintercept.so
distclean: clean
@echo
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Hommel <wolfgang.hommel@unibw.de>
Date: Sun, 8 May 2022 21:05:10 +0200
Subject: [PATCH 12/16] silence minor type warning in libmallocintercept.c
---
test/libmallocintercept.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/libmallocintercept.c b/test/libmallocintercept.c
index 5ed0f67..0dc5af5 100644
--- a/test/libmallocintercept.c
+++ b/test/libmallocintercept.c
@@ -73,11 +73,11 @@ void *malloc(size_t size) {
return actual_malloc(size);
}
-void free(void *) {
+void free(void *ptr) {
+ void *ptr2 = ptr + 1;
print_msg("Called free() from libmallocintercept...");
poke_faketime();
print_msg("successfully\n");
/* We cannot actually free memory */
}
-
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Hommel <wolfgang.hommel@unibw.de>
Date: Sun, 8 May 2022 21:09:45 +0200
Subject: [PATCH 13/16] silence minor type warning in libmallocintercept.c
---
test/libmallocintercept.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/test/libmallocintercept.c b/test/libmallocintercept.c
index 0dc5af5..0cf5aeb 100644
--- a/test/libmallocintercept.c
+++ b/test/libmallocintercept.c
@@ -74,8 +74,7 @@ void *malloc(size_t size) {
}
void free(void *ptr) {
- void *ptr2 = ptr + 1;
- print_msg("Called free() from libmallocintercept...");
+ print_msg("Called free() on %p from libmallocintercept...", ptr);
poke_faketime();
print_msg("successfully\n");
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Hommel <wolfgang.hommel@unibw.de>
Date: Sun, 8 May 2022 21:20:29 +0200
Subject: [PATCH 14/16] silence minor type warning in libmallocintercept.c
---
test/libmallocintercept.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/test/libmallocintercept.c b/test/libmallocintercept.c
index 0cf5aeb..a649e9e 100644
--- a/test/libmallocintercept.c
+++ b/test/libmallocintercept.c
@@ -74,7 +74,8 @@ void *malloc(size_t size) {
}
void free(void *ptr) {
- print_msg("Called free() on %p from libmallocintercept...", ptr);
+ void *ptr2 = ptr; ptr2 -= ptr;
+ print_msg("Called free() on from libmallocintercept...");
poke_faketime();
print_msg("successfully\n");
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Wolfgang Hommel <wolfgang.hommel@unibw.de>
Date: Sun, 8 May 2022 21:24:51 +0200
Subject: [PATCH 15/16] silence minor type warning in libmallocintercept.c
---
test/libmallocintercept.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/libmallocintercept.c b/test/libmallocintercept.c
index a649e9e..e789d34 100644
--- a/test/libmallocintercept.c
+++ b/test/libmallocintercept.c
@@ -74,7 +74,7 @@ void *malloc(size_t size) {
}
void free(void *ptr) {
- void *ptr2 = ptr; ptr2 -= ptr;
+ long int ptr2 = (long int) ptr; ptr2 -= (long int) ptr;
print_msg("Called free() on from libmallocintercept...");
poke_faketime();
print_msg("successfully\n");
--
2.36.1
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Uli Schlachter <psychon@znc.in>
Date: Mon, 9 May 2022 13:53:51 +0200
Subject: [PATCH 16/16] Fix another hang under ASAN
We have a long-running program that we want to run under sanitizers for
extra error checking and under faketime to speed up the clock. This
program hangs after a while. Backtraces suggest that the hangs occur
because of recursion in the memory allocator, which apparently locks a
non-recursive mutex.
Specifically, what we see is that due to our use of FAKETIME_NO_CACHE=1,
libfaketime wants to reload the config file inside a (random) call to
clock_gettime(). libfaketime then uses fopen() / fclose() for reading
the config files. These function allocate / free a buffer for reading
data and specifically the call to free() that happens inside fclose()
ends up calling clock_gettime() again. At this point, libfaketime locks
up because it has a time_mutex that is locked and none-recursive.
Sadly, I did not manage to come up with a stand-alone reproducer for
this problem. Also, the above description is from memory after half a
week of vacation, so it might be (partially) wrong.
More information can be found here:
- https://github.com/wolfcw/libfaketime/issues/365#issuecomment-1115802530
- https://github.com/wolfcw/libfaketime/issues/365#issuecomment-1116178907
This commit first adds a test case. This new test uses the already
existing libmallocintercept.so to cause calls to clock_gettime() during
memory allocation routines. The difference to the already existing
version is that additionally FAKETIME_NO_CACHE and
FAKETIME_TIMESTAMP_FILE are set. This new test hung with its last output
suggesting a recursive call to malloc:
Called malloc() from libmallocintercept...successfully
Called free() on from libmallocintercept...successfully
Called malloc() from libmallocintercept...Called malloc() from libmallocintercept...
Sadly, gdb was unable to provide a meaningful backtrace for this hang.
Next, I replaced the use of fopen()/fgets()/fgets() with
open()/read()/close(). This code no longer reads the config file
line-by-line, but instead it reads all of it at once and then "filters
out" the result (ignores comment lines, removes end of line markers).
I tried to keep the behaviour of the code the same, but I know at least
one difference: Previously, the config file was read line-by-line and
lines that began with a comment character were immediately ignored. The
new code only reads the config once and then removes comment lines.
Since the buffer that is used contains only 256 characters, it is
possible that config files that were previously parsed correctly now
longer parse. A specific example: if a file begins with 500 '#'
characters in its first line and then a timestamp in the second line,
the old code was able to parse this file while the new code would only
see an empty file.
After this change, the new test no longer hangs. Sadly, I do not
actually know its effect on the "actual bug" that I wanted to fix, but
since there are no longer any calls to fclose(), there cannot be any
hangs inside fclose().
Signed-off-by: Uli Schlachter <psychon@znc.in>
---
src/libfaketime.c | 71 ++++++++++++++++++++++++++++-------------------
test/test.sh | 10 +++++++
2 files changed, 53 insertions(+), 28 deletions(-)
diff --git a/src/libfaketime.c b/src/libfaketime.c
index ec80ec8..2f26bd4 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -2968,20 +2968,40 @@ static void ftpl_init(void)
* =======================================================================
*/
-static void remove_trailing_eols(char *line)
+static void prepare_config_contents(char *contents)
{
- char *endp = line + strlen(line);
- /*
- * erase the last char if it's a newline
- * or carriage return, and back up.
- * keep doing this, but don't back up
- * past the beginning of the string.
+ /* This function
+ * - removes line separators (\r and \n)
+ * - removes lines beginning with a comment character (# or ;)
*/
-# define is_eolchar(c) ((c) == '\n' || (c) == '\r')
- while (endp > line && is_eolchar(endp[-1]))
- {
- *--endp = '\0';
+ char *read_position = contents;
+ char *write_position = contents;
+ bool in_comment = false;
+ bool beginning_of_line = true;
+
+ while (*read_position != '\0') {
+ if (beginning_of_line && (*read_position == '#' || *read_position == ';')) {
+ /* The line begins with a comment character and should be completely ignored */
+ in_comment = true;
+ }
+ beginning_of_line = false;
+
+ if (*read_position == '\n') {
+ /* We reached the end of the line that should be ignored (if any is ignored) */
+ in_comment = false;
+ /* The next character begins a new line */
+ beginning_of_line = true;
+ }
+
+ /* If we are not in a comment and are not looking at a line break, copy the
+ * character from the read position to the write position. */
+ if (!in_comment && *read_position != '\r' && *write_position != '\n') {
+ *write_position = *read_position;
+ write_position++;
+ }
+ read_position++;
}
+ *write_position = '\0';
}
@@ -3018,30 +3038,25 @@ int read_config_file()
static char user_faked_time[BUFFERLEN]; /* changed to static for caching in v0.6 */
static char custom_filename[BUFSIZ];
static char filename[BUFSIZ];
- FILE *faketimerc;
+ int faketimerc;
/* check whether there's a .faketimerc in the user's home directory, or
* a system-wide /etc/faketimerc present.
* The /etc/faketimerc handling has been contributed by David Burley,
* Jacob Moorman, and Wayne Davison of SourceForge, Inc. in version 0.6 */
(void) snprintf(custom_filename, BUFSIZ, "%s", getenv("FAKETIME_TIMESTAMP_FILE"));
(void) snprintf(filename, BUFSIZ, "%s/.faketimerc", getenv("HOME"));
- if ((faketimerc = fopen(custom_filename, "rt")) != NULL ||
- (faketimerc = fopen(filename, "rt")) != NULL ||
- (faketimerc = fopen("/etc/faketimerc", "rt")) != NULL)
- {
- static char line[BUFFERLEN];
- while (fgets(line, BUFFERLEN, faketimerc) != NULL)
- {
- if ((strlen(line) > 1) && (line[0] != ' ') &&
- (line[0] != '#') && (line[0] != ';'))
- {
- remove_trailing_eols(line);
- strncpy(user_faked_time, line, BUFFERLEN-1);
- user_faked_time[BUFFERLEN-1] = 0;
- break;
- }
+ if ((faketimerc = open(custom_filename, O_RDONLY)) != -1 ||
+ (faketimerc = open(filename, O_RDONLY)) != -1 ||
+ (faketimerc = open("/etc/faketimerc", O_RDONLY)) != -1)
+ {
+ ssize_t length = read(faketimerc, user_faked_time, sizeof(user_faked_time) - 1);
+ close(faketimerc);
+ if (length < 0) {
+ length = 0;
}
- fclose(faketimerc);
+ user_faked_time[length] = 0;
+
+ prepare_config_contents(user_faked_time);
parse_ft_string(user_faked_time);
return 1;
}
diff --git a/test/test.sh b/test/test.sh
index 1ef7439..b03077d 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -71,6 +71,16 @@ echo "\$ LD_PRELOAD=./libmallocintercept.so:$FTPL ./timetest"
LD_PRELOAD="./libmallocintercept.so:$FTPL" ./timetest
echo
+echo "============================================================================="
+echo
+
+echo "@2005-03-29 14:14:14" > .faketimerc-for-test
+echo "Running the test program with malloc interception and file faketimerc"
+echo "\$ FAKETIME_NO_CACHE=1 FAKETIME_TIMESTAMP_FILE=.faketimerc-for-test LD_PRELOAD=./libmallocintercept.so:$FTPL ./timetest"
+FAKETIME_NO_CACHE=1 FAKETIME_TIMESTAMP_FILE=.faketimerc-for-test LD_PRELOAD="./libmallocintercept.so:$FTPL" ./timetest
+rm .faketimerc-for-test
+echo
+
echo "============================================================================="
echo "Testing finished."
--
2.36.1

View File

@ -1,29 +0,0 @@
From f19d68ea3231f1af7a6e3913dc6d3c46f73947b2 Mon Sep 17 00:00:00 2001
From: Robin Linden <dev@robinlinden.eu>
Date: Thu, 28 May 2020 23:09:07 +0200
Subject: [PATCH] Fix make test build failure on gcc 9.3
On Ubuntu 20.04 using gcc 9.3, make test fails due to a deprecated
function (ftime) warning in combination with -Werror in timetest.c.
Since the warning is from a test testing that the deprecated function
can be replaced using LD_PRELOAD, I think it's reasonable to just
silence the warning in that case.
---
test/timetest.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/test/timetest.c b/test/timetest.c
index e9aa837..c33368c 100644
--- a/test/timetest.c
+++ b/test/timetest.c
@@ -216,7 +216,10 @@ printf("%s", 0 == 1 ? argv[0] : "");
printf("time() : Current date and time: %s", ctime(&now));
printf("time(NULL) : Seconds since Epoch : %u\n", (unsigned int)time(NULL));
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
ftime(&tb);
+#pragma GCC diagnostic pop
printf("ftime() : Current date and time: %s", ctime(&tb.time));
printf("(Intentionally sleeping 2 seconds...)\n");

View File

@ -1,8 +1,8 @@
diff --git a/src/libfaketime.c b/src/libfaketime.c
index b70a3d3..19f6234 100644
index 18e2c94..363f38c 100644
--- a/src/libfaketime.c
+++ b/src/libfaketime.c
@@ -1643,6 +1643,7 @@ timer_settime_common(timer_t_or_int timerid, int flags,
@@ -1936,6 +1936,7 @@ timer_settime_common(timer_t_or_int timerid, int flags,
/*
* Faked timer_settime() compatible with implementation in GLIBC 2.2
*/
@ -10,7 +10,7 @@ index b70a3d3..19f6234 100644
int timer_settime_22(int timerid, int flags,
const struct itimerspec *new_value,
struct itimerspec *old_value)
@@ -1665,6 +1666,7 @@ int timer_settime_22(int timerid, int flags,
@@ -1958,6 +1959,7 @@ int timer_settime_22(int timerid, int flags,
/*
* Faked timer_settime() compatible with implementation in GLIBC 2.3.3
*/
@ -18,7 +18,7 @@ index b70a3d3..19f6234 100644
int timer_settime_233(timer_t timerid, int flags,
const struct itimerspec *new_value,
struct itimerspec *old_value)
@@ -1735,6 +1737,7 @@ int timer_gettime_common(timer_t_or_int timerid, struct itimerspec *curr_value,
@@ -2031,6 +2033,7 @@ int timer_gettime_common(timer_t_or_int timerid, struct itimerspec *curr_value,
/*
* Faked timer_gettime() compatible with implementation in GLIBC 2.2
*/
@ -26,7 +26,7 @@ index b70a3d3..19f6234 100644
int timer_gettime_22(timer_t timerid, struct itimerspec *curr_value)
{
if (!initialized)
@@ -1755,6 +1758,7 @@ int timer_gettime_22(timer_t timerid, struct itimerspec *curr_value)
@@ -2051,6 +2054,7 @@ int timer_gettime_22(timer_t timerid, struct itimerspec *curr_value)
/*
* Faked timer_gettime() compatible with implementation in GLIBC 2.3.3
*/
@ -34,7 +34,7 @@ index b70a3d3..19f6234 100644
int timer_gettime_233(timer_t timerid, struct itimerspec *curr_value)
{
if (!initialized)
@@ -1772,10 +1776,6 @@ int timer_gettime_233(timer_t timerid, struct itimerspec *curr_value)
@@ -2068,10 +2072,6 @@ int timer_gettime_233(timer_t timerid, struct itimerspec *curr_value)
}
}
@ -43,9 +43,9 @@ index b70a3d3..19f6234 100644
-__asm__(".symver timer_settime_22, timer_settime@GLIBC_2.2");
-__asm__(".symver timer_settime_233, timer_settime@@GLIBC_2.3.3");
#endif
#endif
@@ -3012,6 +3012,11 @@ struct pthread_cond_monotonic {
#ifdef __linux__
/*
@@ -3463,6 +3463,11 @@ struct pthread_cond_monotonic {
static struct pthread_cond_monotonic *monotonic_conds = NULL;
@ -57,7 +57,7 @@ index b70a3d3..19f6234 100644
int pthread_cond_init_232(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr)
{
clockid_t clock_id;
@@ -3039,6 +3044,11 @@ int pthread_cond_init_232(pthread_cond_t *restrict cond, const pthread_condattr_
@@ -3501,6 +3506,11 @@ int pthread_cond_init_232(pthread_cond_t *restrict cond, const pthread_condattr_
return result;
}
@ -69,7 +69,7 @@ index b70a3d3..19f6234 100644
int pthread_cond_destroy_232(pthread_cond_t *cond)
{
struct pthread_cond_monotonic* e;
@@ -3146,26 +3156,22 @@ int pthread_cond_timedwait_common(pthread_cond_t *cond, pthread_mutex_t *mutex,
@@ -3608,26 +3618,22 @@ int pthread_cond_timedwait_common(pthread_cond_t *cond, pthread_mutex_t *mutex,
return result;
}

View File

@ -1,13 +1,14 @@
Summary: Manipulate system time per process for testing purposes
Name: libfaketime
Version: 0.9.8
Release: 13%{?dist}
Version: 0.9.10
Release: 1%{?dist}
License: GPLv2+
Url: https://github.com/wolfcw/libfaketime
Source: libfaketime-0.9.8.tar.xz
Patch0: libfaketime-0.9.8-FORCE_PTHREAD_NONVER.patch
Source: libfaketime-0.9.10.tar.gz
Patch0: libfaketime-backports.patch
Patch1: libfaketime-symver.patch
Patch2: libfaketime-fixgcc10.patch
Patch2: 0001-Disable-unused-result-warning-in-tests.patch
Patch3: 0001-Fix-gettimeofday-aarch64_epel8.patch
Provides: faketime
@ -15,6 +16,9 @@ BuildRequires: gcc
BuildRequires: perl-interpreter
BuildRequires: perl-Time-HiRes
BuildRequires: make
%if 0%{?fedora} >= 36
Excludearch: %{ix86} %{arm}
%endif
%description
libfaketime intercepts various system calls which programs use to
@ -29,9 +33,17 @@ time system- wide.
%if 0%{?fedora} >= 32 || 0%{?rhel} >= 9
%patch1 -p1
%endif
%if 0%{?fedora} >= 36
%patch2 -p1
%endif
%if 0%{?rhel} == 8
%ifarch aarch64
%patch3 -p1
%endif
%endif
%build
cd src
# https://github.com/wolfcw/libfaketime/blob/master/README.packagers
@ -62,7 +74,7 @@ FAKETIME_COMPILE_CFLAGS="BOGUS"
unset FAKETIME_COMPILE_CFLAGS
%endif
%endif
%if 0%{?fedora} >= 31
%if 0%{?fedora} >= 31 || 0%{?rhel} >=9
# for reasons we don't know the old glibc workaround is required here but not on archv7hl and aarch64 ...
%ifarch i686 x86_64 s390x
echo "force_monotonic"
@ -104,6 +116,10 @@ chmod a+rx %{buildroot}/%{_libdir}/faketime/*.so.*
%{_mandir}/man1/*
%changelog
* Tue May 10 2022 Pablo Greco <pgreco@centosproject.org> - 0.9.10-1
- Update to 0.9.10
- Disable i686 and armhfp in fedora >=36
* Thu Jan 20 2022 Fedora Release Engineering <releng@fedoraproject.org> - 0.9.8-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild

View File

@ -1 +1 @@
SHA512 (libfaketime-0.9.8.tar.xz) = 6b0deab7aea6b68c3a1e77c022d7a907b7337f75cfce510044c239c7f789e73ed5f1ee3b23ea5b6c8b0cb723c41ed95c1dd9738cca49b9c9840b9022fbfb57b1
SHA512 (libfaketime-0.9.10.tar.gz) = 07c431bee21e31343b680d1322dd529ea276e3cc4dbec61646c12bf5d0263163faf6186efeb36b199e24b655578a493c43e3b7a7acf8eba8b9ff84a1e94d618b