commit 921f41ccd2fa9026770b1f735c36b503c42704c2 Author: tigro Date: Sat Dec 14 23:12:13 2024 +0300 import libfaketime-0.9.10-11.el10 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1ae07f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/libfaketime-0.9.10.tar.gz diff --git a/.libfaketime.metadata b/.libfaketime.metadata new file mode 100644 index 0000000..85d4942 --- /dev/null +++ b/.libfaketime.metadata @@ -0,0 +1 @@ +b2f660ca1aea0ef95b0f3f8e3304786df27c1fa7 SOURCES/libfaketime-0.9.10.tar.gz diff --git a/SOURCES/0001-Disable-unused-result-warning-in-tests.patch b/SOURCES/0001-Disable-unused-result-warning-in-tests.patch new file mode 100644 index 0000000..4ab079c --- /dev/null +++ b/SOURCES/0001-Disable-unused-result-warning-in-tests.patch @@ -0,0 +1,27 @@ +From eaa86dbed279351c845f5ed9525595ee9714b166 Mon Sep 17 00:00:00 2001 +From: Pablo Greco +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 + + 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 + diff --git a/SOURCES/libfaketime-backports.patch b/SOURCES/libfaketime-backports.patch new file mode 100644 index 0000000..ee4c58e --- /dev/null +++ b/SOURCES/libfaketime-backports.patch @@ -0,0 +1,874 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Wolfgang Hommel +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 +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 + + 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 +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 +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 +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 +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 +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 +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 +--- + 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 ++#include ++#include ++#include ++#include ++ ++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, ×pec); ++ 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 +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 +--- + 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 +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 +--- + 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, ×pec); + 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 +Date: Sun, 8 May 2022 19:20:51 +0200 +Subject: [PATCH 11/16] Add libmallocintercept.so to make clean + +Signed-off-by: Uli Schlachter +--- + 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 +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 +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 +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 +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 +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 +--- + 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 + diff --git a/SOURCES/libfaketime-symver.patch b/SOURCES/libfaketime-symver.patch new file mode 100644 index 0000000..6c13f85 --- /dev/null +++ b/SOURCES/libfaketime-symver.patch @@ -0,0 +1,104 @@ +diff --git a/src/libfaketime.c b/src/libfaketime.c +index 18e2c94..363f38c 100644 +--- a/src/libfaketime.c ++++ b/src/libfaketime.c +@@ -1936,6 +1936,7 @@ timer_settime_common(timer_t_or_int timerid, int flags, + /* + * Faked timer_settime() compatible with implementation in GLIBC 2.2 + */ ++__attribute__ ((symver ("timer_settime@GLIBC_2.2"))) + int timer_settime_22(int timerid, int flags, + const struct itimerspec *new_value, + struct itimerspec *old_value) +@@ -1958,6 +1959,7 @@ int timer_settime_22(int timerid, int flags, + /* + * Faked timer_settime() compatible with implementation in GLIBC 2.3.3 + */ ++__attribute__ ((symver ("timer_settime@@GLIBC_2.3.3"))) + int timer_settime_233(timer_t timerid, int flags, + const struct itimerspec *new_value, + struct itimerspec *old_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 + */ ++__attribute__ ((symver ("timer_gettime@GLIBC_2.2"))) + int timer_gettime_22(timer_t timerid, struct itimerspec *curr_value) + { + if (!initialized) +@@ -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 + */ ++__attribute__ ((symver ("timer_gettime@@GLIBC_2.3.3"))) + int timer_gettime_233(timer_t timerid, struct itimerspec *curr_value) + { + if (!initialized) +@@ -2068,10 +2072,6 @@ int timer_gettime_233(timer_t timerid, struct itimerspec *curr_value) + } + } + +-__asm__(".symver timer_gettime_22, timer_gettime@GLIBC_2.2"); +-__asm__(".symver timer_gettime_233, timer_gettime@@GLIBC_2.3.3"); +-__asm__(".symver timer_settime_22, timer_settime@GLIBC_2.2"); +-__asm__(".symver timer_settime_233, timer_settime@@GLIBC_2.3.3"); + + #ifdef __linux__ + /* +@@ -3463,6 +3463,11 @@ struct pthread_cond_monotonic { + + static struct pthread_cond_monotonic *monotonic_conds = NULL; + ++#if defined __ARM_ARCH || defined FORCE_PTHREAD_NONVER ++__attribute__ ((symver ("pthread_cond_init@@"))) ++#else ++__attribute__ ((symver ("pthread_cond_init@@GLIBC_2.3.2"))) ++#endif + int pthread_cond_init_232(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr) + { + clockid_t clock_id; +@@ -3501,6 +3506,11 @@ int pthread_cond_init_232(pthread_cond_t *restrict cond, const pthread_condattr_ + return result; + } + ++#if defined __ARM_ARCH || defined FORCE_PTHREAD_NONVER ++__attribute__ ((symver ("pthread_cond_destroy@@"))) ++#else ++__attribute__ ((symver ("pthread_cond_destroy@@GLIBC_2.3.2"))) ++#endif + int pthread_cond_destroy_232(pthread_cond_t *cond) + { + struct pthread_cond_monotonic* e; +@@ -3608,26 +3618,22 @@ int pthread_cond_timedwait_common(pthread_cond_t *cond, pthread_mutex_t *mutex, + return result; + } + ++__attribute__ ((symver ("pthread_cond_timedwait@GLIBC_2.2.5"))) + int pthread_cond_timedwait_225(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) + { + return pthread_cond_timedwait_common(cond, mutex, abstime, FT_COMPAT_GLIBC_2_2_5); + } + ++#if defined __ARM_ARCH || defined FORCE_PTHREAD_NONVER ++__attribute__ ((symver ("pthread_cond_timedwait@@"))) ++#else ++__attribute__ ((symver ("pthread_cond_timedwait@@GLIBC_2.3.2"))) ++#endif + int pthread_cond_timedwait_232(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) + { + return pthread_cond_timedwait_common(cond, mutex, abstime, FT_COMPAT_GLIBC_2_3_2); + } + +-__asm__(".symver pthread_cond_timedwait_225, pthread_cond_timedwait@GLIBC_2.2.5"); +-#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@@"); +-#else +-__asm__(".symver pthread_cond_timedwait_232, pthread_cond_timedwait@@GLIBC_2.3.2"); +-__asm__(".symver pthread_cond_init_232, pthread_cond_init@@GLIBC_2.3.2"); +-__asm__(".symver pthread_cond_destroy_232, pthread_cond_destroy@@GLIBC_2.3.2"); +-#endif + + #endif + diff --git a/SPECS/libfaketime.spec b/SPECS/libfaketime.spec new file mode 100644 index 0000000..44a0c5d --- /dev/null +++ b/SPECS/libfaketime.spec @@ -0,0 +1,233 @@ +Summary: Manipulate system time per process for testing purposes +Name: libfaketime +Version: 0.9.10 +Release: 11%{?dist} +# most of the code is GPL-2.0-or-later AND GPL-3.0-only +# part of src/libfaketime.c is GPLv3 +License: GPL-2.0-or-later AND GPL-3.0-only +Url: https://github.com/wolfcw/libfaketime +Source: https://github.com/wolfcw/libfaketime/archive/v%{version}/%{name}-%{version}.tar.gz + +Patch0: libfaketime-backports.patch +Patch1: libfaketime-symver.patch +Patch2: 0001-Disable-unused-result-warning-in-tests.patch + +Provides: faketime = %{version} + +BuildRequires: gcc +BuildRequires: perl-interpreter +BuildRequires: perl-Time-HiRes +BuildRequires: make +%if 0%{?fedora} >= 36 || 0%{?rhel} >= 10 +Excludearch: %{ix86} %{arm} +%endif + +%description +libfaketime intercepts various system calls which programs use to +retrieve the current date and time. It can then report faked dates and +times (as specified by you, the user) to these programs. This means you +can modify the system time a program sees without having to change the +time system- wide. + +%prep +%autosetup -p1 + +%build + +cd src + +# https://github.com/wolfcw/libfaketime/blob/master/README.packagers +# Upstream libfaketime requires a mess of different compile time flags for different glibc versions and architectures. +# https://github.com/wolfcw/libfaketime/pull/178 +# Goal is to build time autodetect these with autotools in the next release ... + +FAKETIME_COMPILE_CFLAGS="BOGUS" +%if 0%{?el7} + %ifarch x86_64 + echo "force_monotonic https://github.com/wolfcw/libfaketime/issues/202" + export FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX" + %endif + %ifarch aarch64 ppc64le + echo "force_monotonic and pthread_nonver https://github.com/wolfcw/libfaketime/issues/205" + export FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX -DFORCE_PTHREAD_NONVER" + %endif + %ifarch armv7hl + unset FAKETIME_COMPILE_CFLAGS + %endif +%endif +%if 0%{?fedora} == 30 || 0%{?el8} + # only ppc64le needs a workaround + %ifarch ppc64le + echo "pthread_nonver https://github.com/wolfcw/libfaketime/issues/204" + export FAKETIME_COMPILE_CFLAGS="-DFORCE_PTHREAD_NONVER" + %else + unset FAKETIME_COMPILE_CFLAGS + %endif +%endif +%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" + export FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX" + %endif + %ifarch ppc64le riscv64 + echo "force_monotonic and pthread_nonver" + export FAKETIME_COMPILE_CFLAGS="-DFORCE_MONOTONIC_FIX -DFORCE_PTHREAD_NONVER" + %endif + %ifarch armv7hl aarch64 + unset FAKETIME_COMPILE_CFLAGS + %endif +%endif + +if [ "$FAKETIME_COMPILE_CFLAGS" == "BOGUS" ]; then + echo "SHOULD NEVER REACH HERE ... YOU HAVE AN UNTESTED VERSION+ARCH, see rpm spec for details ... ABORT" + exit 1 +fi + +CFLAGS="%{optflags} -Wno-nonnull-compare -Wno-strict-aliasing" make %{?_smp_mflags} \ + PREFIX="%{_prefix}" LIBDIRNAME="/%{_lib}/faketime" all + +%check +make %{?_smp_mflags} -C test + +%install +make PREFIX="%{_prefix}" DESTDIR=%{buildroot} LIBDIRNAME="/%{_lib}/faketime" install +rm -r %{buildroot}/%{_docdir}/faketime +# needed for stripping/debug package +chmod a+rx %{buildroot}/%{_libdir}/faketime/*.so.* + + +%files +%{_bindir}/faketime +%dir %attr(0755, root, root) %{_libdir}/faketime/ +%attr(0755, root, root) %{_libdir}/faketime/libfaketime*so.* +%license COPYING +%doc README NEWS README.developers +%{_mandir}/man1/* + +%changelog +* Sat Dec 14 2024 Arkady L. Shane - 0.9.10-11 +- Rebuilt for MSVSphere 10 + +* Tue Oct 29 2024 Troy Dawson - 0.9.10-11 +- Bump release for October 2024 mass rebuild: + Resolves: RHEL-64018 + +* Mon Jun 24 2024 Troy Dawson - 0.9.10-10 +- Bump release for June 2024 mass rebuild + +* Thu Jan 25 2024 Fedora Release Engineering - 0.9.10-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Sun Jan 21 2024 Fedora Release Engineering - 0.9.10-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + +* Wed Jan 10 2024 Paul Wouters - 0.9.10-7 +- Fix for building for riscv64 + +* Thu Jul 20 2023 Fedora Release Engineering - 0.9.10-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + +* Wed Feb 22 2023 Pablo Greco - 0.9.10-5 +- Fix tests in ELN builds (yselkowitz) + +* Tue Feb 21 2023 Pablo Greco - 0.9.10-4 +- Also disable i686 in rhel>=10 (ELN failures) + +* Thu Jan 19 2023 Fedora Release Engineering - 0.9.10-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + +* Thu Jul 21 2022 Fedora Release Engineering - 0.9.10-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + +* Tue May 10 2022 Pablo Greco - 0.9.10-1 +- Update to 0.9.10 +- Disable i686 and armhfp in fedora >=36 + +* Thu Jan 20 2022 Fedora Release Engineering - 0.9.8-13 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + +* Thu Jul 22 2021 Fedora Release Engineering - 0.9.8-12 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + +* Tue Jan 26 2021 Fedora Release Engineering - 0.9.8-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild + +* Wed Sep 02 2020 Pablo Greco - 0.9.8-10 +- Conditionals to build 0.9.8-9 in f31 and epel7-8 +- Use upstream's version of the gcc10 fix + +* Wed Sep 02 2020 Jeff Law - 0.9.8-9 +- Use symver attribute instead of asms for symbol versioning +- Enable LTO + +* Tue Jul 28 2020 Fedora Release Engineering - 0.9.8-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + +* Fri Jul 10 2020 Jeff Law - 0.9.8-7 +- Disable LTO + +* Sat Feb 08 2020 Pablo Greco - 0.9.8-6 +- Fix build with gcc10 + +* Wed Jan 29 2020 Fedora Release Engineering - 0.9.8-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + +* Tue Oct 29 2019 Paul Wouters - 0.9.8-5 +- Resolves: rhbz#1766749 libfaketime rfe: please add Provides:faketime +- Use license tag, remove duplicate README entry, update make test target + +* Tue Sep 03 2019 Warren Togami - 0.9.8-4 +- upstream says to use FORCE_PTHREAD_NONVER on any glibc+arch that gets stuck + For Fedora 31+ "make test" gets stuck on i686 x86_64 ppc64le s390x + +* Wed Aug 28 2019 Warren Togami - 0.9.8-3 +- 0.9.8 +- x86_64 EL7: DFORCE_MONOTONIC_FIX + aarch64 EL7: DFORCE_MONOTONIC_FIX and FORCE_PTHREAD_NONVER + ppc64le EL7: DFORCE_MONOTONIC_FIX and FORCE_PTHREAD_NONVER + ppc64le F30+ FORCE_PTHREAD_NONVER + +* Fri Feb 01 2019 Fedora Release Engineering - 0.9.6-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + +* Fri Jul 13 2018 Fedora Release Engineering - 0.9.6-8 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Wed Feb 07 2018 Fedora Release Engineering - 0.9.6-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Thu Aug 03 2017 Fedora Release Engineering - 0.9.6-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Wed Jul 26 2017 Fedora Release Engineering - 0.9.6-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Fri Feb 10 2017 Fedora Release Engineering - 0.9.6-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Wed Oct 12 2016 Paul Wouters - 0.9.6-4 +- Add support for CLOCK_BOOTTIME (patch by Mario Pareja ) + +* Thu Feb 04 2016 Fedora Release Engineering - 0.9.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Wed Jun 17 2015 Fedora Release Engineering - 0.9.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + +* Tue Oct 28 2014 Paul Wouters - 0.9.6-1 +- Upgraded to 0.9.6 which adds option to disable monotonic time faking +- fix permissions for symbol stripping for debug package + +* Tue Oct 15 2013 Paul Wouters - 0.9.5-4 +- Infinite recursion patch is still needed, make test causes + segfaults otherwise. + +* Mon Oct 14 2013 Paul Wouters - 0.9.5-3 +- Work around from upstream for autodetecting glibc version bug on i686 + +* Mon Oct 14 2013 Paul Wouters - 0.9.5-2 +- Remove use of ifarch for _lib macro for multilib + +* Sun Oct 13 2013 Paul Wouters - 0.9.5-1 +- Initial package