libfaketime, version 0.9.10 (March 2022) ======================================== Content of this file: --------------------- 1. Introduction 2. Compatibility issues 3. Installation 4. Usage a) Basics b) Using absolute dates c) Using 'start at' dates d) Using offsets for relative dates e) Advanced features and caveats f) Faking the date and time system-wide g) Using the "faketime" wrapper script h) "Limiting" libfaketime based on elapsed time or number of calls i) "Limiting" libfaketime per process j) Spawning an external process k) Saving timestamps to file, loading them from file l) Replacing random numbers with deterministic number sequences 5. License 6. Contact 1. Introduction --------------- libfaketime intercepts various system calls that programs use to retrieve the current date and time. It then reports modified (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. libfaketime allows you to specify both absolute dates (e.g., 01/01/2004) and relative dates (e.g., 10 days ago). libfaketime might be used for various purposes, for example - deterministic build processes - debugging time-related issues, such as expired SSL certificates - testing software for year-2038 compliance libfaketime ships with a command line wrapper called "faketime" that makes it easier to use, but does not expose all of libfaketime's functionality. If your use case is not covered by the faketime command, make sure to look in this documentation whether it can be achieved by using libfaketime directly. 2. Compatibility issues ----------------------- - libfaketime is supposed to work on Linux and macOS. Your mileage may vary; some other *NIXes have been reported to work as well. - libfaketime uses the library preload mechanism of your operating system's linker (which is involved in starting programs) and thus cannot work with statically linked binaries or binaries that have the setuid-flag set (e.g., suidroot programs like "ping" or "passwd"). Please see you system linker's manpage for further details. - libfaketime supports the pthreads environment. A separate library is built (libfaketimeMT.so.1), which contains the pthread synchronization calls. This library also single-threads calls through the time() intercept because several variables are statically cached by the library and could cause issues when accessed without synchronization. However, the performance penalty for this might be an issue for some applications. If this is the case, you can try using an unsynchronized time() intercept by removing the -DPTHREAD_SINGLETHREADED_TIME from the Makefile and rebuilding libfaketimeMT.so.1 * Java-/JVM-based applications work but you need to pass in an extra argument (FAKETIME_DONT_FAKE_MONOTONIC). See usage basics below for details. Without this argument the java command usually hangs. * libfaketime will eventually be bypassed by applications that dynamically load system libraries, such as librt, explicitly themselves instead of relying on the linker to do so at application start time. libfaketime will not work with those applications unless you can modify them. This apparently happens a lot in complex run-time environments, e.g., for programs written in golang, for some Java Virtual Machine implementations, etc. Since libfaketime is effectively bypassed in such situations, there's nothing we can do about it. Please consider asking the appropriate developers and vendors to implement their runtime environment in a way that supports intercepting selected system calls through LD_PRELOAD. * Applications can explicitly be designed to prevent libfaketime from working, e.g., by checking whether certain environment variables are set or whether libfaketime-specific files are present. * CLOCK_MONOTONIC test: Running "make test" performs a series of tests after successful compilation of the libfaketime library. On some platforms, the "CLOCK_MONOTONIC test" will apparently hang forever. If and only if this happens on your platform, add the CFLAG -DFORCE_MONOTONIC_FIX to src/Makefile and recompile libfaketime. Do not set FORCE_MONOTONIC_FIX on platforms where the test does not hang. If you observe hangs on the CLOCK_REALTIME test, add the CFLAG -DFORCE_PTHREAD_NONVER. Also set this FORCE_PTHREAD_NONVER flag in case FORCE_MONOTONIC_FIX alone does not solve the hang on the MONOTONIC_CLOCK test. If FORCE_MONOTONIC_FIX was not set as a compile-time flag, you can also set an environment variable FAKETIME_FORCE_MONOTONIC_FIX=1 if you want to enable the fix at run-time, or to 0 if you explicitly want to disable it. The fix is automatically enabled if libfaketime was compiled on a system with glibc as the underlying libc implementation, and a glibc version is detected at run-time that is assumed to need this workaround. Please use Github issues at https://github.com/wolfcw/libfaketime/issues to report any observed hangs during CLOCK_MONOTONIC tests and report your CPU architecture, libc implementation (e.g., glibc 2.30) and any other details that might help (e.g., Linux distribution, use within, e.g., Docker containers etc.). Please try to avoid compiling with FORCE_MONOTONIC_FIX on platforms that do not need it. While it won't make a difference in most cases, depending on the specific FAKETIME settings in use, it would cause certain intercepted functions such as pthread_cond_timedwait() return with a time-out too early or too late, which could break some applications. Try compiling without FORCE_MONOTONIC_FIX first and check whether the tests appear to hang. If they do, you can either set the FAKETIME_FORCE_MONOTONIC_FIX environment variable to 1, or re-compile with FORCE_MONOTONIC_FIX set. 3. Installation --------------- Running "make" compiles both library versions and a test program, which it then also executes. If the test works fine, you should copy the libfaketime libraries (libfaketime.so.1, and libfaketimeMT.so.1) to the place you want them in. Running "make install" will attempt to place them in /usr/local/lib/faketime and will install the wrapper shell script "faketime" in /usr/local/bin, both of which most likely will require root privileges. However, from a technical point of view, there is no necessity for a system-wide installation, so you can use libfaketime also on machines where you do not have root privileges. You may want to adjust the PREFIX variable in the Makefiles accordingly. By default, the Makefile compiles/links libfaketime for your default system architecture. If you need to build, e.g., 32-bit files on a 64-bit platform, please see the notes about CFLAGS and LDFLAGS in src/Makefile. Since version 0.6, system calls to file timestamps are also intercepted, thanks to a contribution by Philipp Hachtmann. This is especially useful in combination with relative time offsets as explained in section 4d) below, if a program writes and reads files whose timestamps also shall be faked. If you do not need this feature or if it confuses the application you want to use FTPL with, define the environment variable NO_FAKE_STAT, and the intercepted stat calls will be passed through unaltered. On macOS, it is necessary to compile differently, due to the different behavior dyld has. Use the Makefile.OSX file provided to compile libfaketime.1.dylib. Additionally, instead of using LD_PRELOAD, the variable DYLD_INSERT_LIBRARIES should be set to the path to libfaketime.1.dylib, and the variable DYLD_FORCE_FLAT_NAMESPACE should be set (to anything). macOS users should read README.OSX for additional details. 4. Usage -------- 4a) Usage basics ---------------- Using libfaketime on a program of your choice consists of two steps: 1. Making sure libfaketime gets loaded by the system's linker. 2. Specify the faked time. As an example, we want the "date" command to report our faked time. To do so, we could use the following command line on Linux: user@host> date Tue Nov 23 12:01:05 CEST 2016 user@host> LD_PRELOAD=/usr/local/lib/libfaketime.so.1 FAKETIME="-15d" date Mon Nov 8 12:01:12 CEST 2016 user@host> LD_PRELOAD=/usr/local/lib/libfaketime.so.1 FAKETIME="-15d" FAKETIME_DONT_FAKE_MONOTONIC=1 java -version java version "1.8.0_111" Java(TM) SE Runtime Environment (build 1.8.0_111-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode) The basic way of running any command/program with libfaketime enabled is to make sure the environment variable LD_PRELOAD contains the path and filename of the libfaketime library. This can either be done by setting it once beforehand: export LD_PRELOAD=/path/to/libfaketime.so.1 (now run any command you want) Or it can be done by specifying it on the command line itself: LD_PRELOAD=/path/to/libfaketime.so.1 your_command_here (These examples are for the bash shell; how environment variables are set may vary on your system.) On Linux, library search paths can be set as part of the linker configuration. LD_PRELOAD then also works with relative paths. For example, when libfaketime.so.1 is installed as /path/to/libfaketime.so.1, you can add /path/to to an appropriate linker configuration file, e.g., /etc/ld.so.conf.d/local.conf, and then run the "ldconfig" command. Afterwards, using LD_PRELOAD=libfaketime.so.1 suffices. However, also the faked time should be specified; otherwise, libfaketime will be loaded, but just report the real system time. There are multiple ways to specify the faked time: a) By setting the environment variable FAKETIME. b) By using the file given in the environment variable FAKETIME_TIMESTAMP_FILE c) By using the file .faketimerc in your home directory. d) By using the file /etc/faketimerc for a system-wide default. e) By using FAKETIME_UPDATE_TIMESTAMP_FILE and date -s "