Commit Graph

108 Commits

Author SHA1 Message Date
Andrij Abyzov
e21bf3017a Fix cross-arch shared memory struct layout and ftruncate/munmap sizes
Replace struct timespec (arch-dependent long/time_t) with fixed-width
int64_t pairs in ft_shared_s so that 32-bit and 64-bit processes
interpret the same shared memory layout identically.

Fix ftruncate calls that allocated sizeof(uint64_t) (8 bytes) instead
of sizeof(struct ft_shared_s) (64-80 bytes) for the shared memory
region. Fix munmap in ft_cleanup using the wrong size.

Add struct layout test and cross-process shared memory functional test.
2026-01-26 13:31:55 +01:00
Petr Písař
712733e5f0 tests: Silence an unused-but-set-variable warning with GCC 16
Compiling tests with GCC 16 results into this warning:

    gcc -shared -o libmallocintercept.so -fpic -std=gnu99 -Wall -DFAKE_STAT -Werror -Wextra  -U_FILE_OFFSET_BITS -U_TIME_BITS libmallocintercept.c
    libmallocintercept.c: In function ‘free’:
    libmallocintercept.c:79:12: error: variable ‘ptr2’ set but not used [-Werror=unused-but-set-variable=]
       79 |   long int ptr2 = (long int) ptr; ptr2 -= (long int) ptr;
	  |            ^~~~
    cc1: all warnings being treated as errors

The ptr2 variable was added in the past to silence compiler warnings,
probably for the very same reason (commits
75cbe8e507 and
2bfbe19f71). GCC 16 is smarter and
discovers that the ptr2 variables is not needed.

This patch changes the work around to "(void) unused_variable;" idiom
recommended by GCC manual and already used in print_msg().
2026-01-06 10:34:39 +01:00
Balint Reczey
3109728f45 Fake the clock_nanosleep syscall 2025-11-08 17:28:48 +01:00
Bjørn Forsman
9d63a80062 tests: replace /bin/bash with bash
For portability.
2025-09-24 15:03:34 +02:00
Bjørn Forsman
cccce3bf23 Replace #!/bin/bash shebangs with #!/usr/bin/env bash
For portability. E.g. /bin/bash doesn't exist on NixOS.
2025-09-24 15:02:44 +02:00
Sammy Tran
a2e406c669 Fix MONOTONIC pthread_cond_timedwait when REALTIME is set 2025-06-13 17:13:43 -04:00
Helge Deller
536889d797 Interpose clock_gettime64
Since debian generally added 64-bit time support on 32-bit
arches, now glibc sometimes calls the clock_gettime64 syscall
(and library wrapper).  This function was missing, and is added here.

Patch originally supplied here
  https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1064555
2025-01-27 12:26:40 +00:00
Gianfranco Costamagna
0516055224 test/libmallocintercept.c: fix write function unused return value
We should ignore the return value for logging function, to fix a new gcc ftbfs
libmallocintercept.c: In function ‘print_msg’:
libmallocintercept.c:27:9: error: ignoring return value of ‘write’ declared with attribute ‘warn_unused_result’ [-Werror=unused-result]
   27 |         write(0, msg, strlen(msg));
      |         ^~~~~~~~~~~~~~~~~~~~~~~~~~
2025-01-22 12:22:37 +01:00
Nick Rosbrook
ccc9992840 test/snippets: fix time.c compiler error on 32-bit arches
Cast t to unsigned long and use the %lu format specifier instead of %zd.
This is more portable to 32-bit arches, avoiding the following compiler
error:

 snippets/time.c:2:31: error: format ‘%zd’ expects argument of type ‘signed size_t’, but argument 3 has type ‘time_t’ {aka ‘long int’} [-Werror=format=]
     2 | printf("[%s] time() yielded %zd\n", where, t);
       |                             ~~^            ~
       |                               |            |
       |                               int          time_t {aka long int}
       |                             %ld
 cc1: all warnings being treated as errors
2022-08-10 14:40:42 -04:00
Uli Schlachter
3b3f80a42f 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>
2022-05-09 13:53:51 +02:00
Wolfgang Hommel
2bfbe19f71 silence minor type warning in libmallocintercept.c 2022-05-08 21:24:51 +02:00
Wolfgang Hommel
75cbe8e507 silence minor type warning in libmallocintercept.c 2022-05-08 21:20:29 +02:00
Wolfgang Hommel
e8838709ea silence minor type warning in libmallocintercept.c 2022-05-08 21:09:45 +02:00
Wolfgang Hommel
bf3a08b04d silence minor type warning in libmallocintercept.c 2022-05-08 21:05:10 +02:00
Uli Schlachter
0f79f21e11 Add libmallocintercept.so to make clean
Signed-off-by: Uli Schlachter <psychon@znc.in>
2022-05-08 19:20:51 +02:00
Uli Schlachter
450d5d4549 Disable FAILRE_PRE_INIT_CALLS by default
Signed-off-by: Uli Schlachter <psychon@znc.in>
2022-05-08 19:17:27 +02:00
Uli Schlachter
6e0f978079 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>
2022-05-04 14:25:13 +02:00
Wolfgang Hommel
f836ea3eb3 Merge pull request #388 from dkg/cleanup-random-tests
test: remember to clean up repeat_random
2022-04-16 21:17:55 +02:00
Daniel Kahn Gillmor
03cb104691 test: remember to clean up repeat_random 2022-04-16 10:27:53 -07:00
Daniel Kahn Gillmor
7e86fb5419 tests: avoid testing syscall snippets if -DINTERCEPT_SYSCALL is not set
See https://bugs.debian.org/1007828
2022-04-16 10:06:23 -07:00
Daniel Kahn Gillmor
e9c74131fc tests: clean whitespace in Makefile 2022-04-16 10:05:40 -07:00
Wolfgang Hommel
a8d6a76906 encourage forced monotonic fix issue reports during test (addresses #366) 2022-02-25 21:36:38 +01:00
Wolfgang Hommel
4bab3179ce Unlock mutex before exiting in case of error (fixes #340) 2021-07-17 19:44:20 +02:00
Daniel Kahn Gillmor
6733dc3a8d tests: Confirm variadic argument promotion assumptions when INTERCEPT_SYSCALL
The test suite should not succeed if INTERCEPT_SYSCALL is defined but
the variadic argument promotion test fails.

OTOH, if we're not asking for INTERCEPT_SYSCALL, we don't care about
the results of that test.
2021-03-05 22:48:47 -05:00
Daniel Kahn Gillmor
008d33fdf2 Test assumptions about variadic re-packing
This test uses the same style of re-packing variadic arguments through
two layers of variadic calls, and compares that call chain against one
direct variadic call.

The outer function uses the same kind of re-packing used in
src/libfaketime.c's syscall (leading to real_syscall), but the inner
functions use different assumptions about the types of each argument.

This is not an entirely comprehensive test, because we only define two
different inner function signatures.  If some particular syscall is
breaking when intercepted, consider adding something like its expected
function signature in test/variadic/inner.c, and invoke it in
test/variadic/main.c.

Note that we don't test any floating point types (those types are
typically passed in registers in x86-64, not on the stack, and are
also not used for any syscall that i'm aware of).
2021-03-05 22:48:47 -05:00
Daniel Kahn Gillmor
51f1248593 tests: use CFLAGS from the environment.
This makes the test build process use the same sort of CFLAGS as the rest of the code.
2021-03-05 21:45:23 -05:00
Daniel Kahn Gillmor
e70b143733 Prepare to add new tests depending on the definitions
We want to be able to conditionally add tests.  This sets up to be
able to do that cleanly.
2021-03-05 21:45:23 -05:00
Daniel Kahn Gillmor
d3f3ee38c6 Add syscall_clock_gettime_heap snippet
This invokes clock_gettime, but uses a timespec from the heap instead
of the stack.

It appears to be successful for me on x86-64 GNU/Linux.

This rules out one possible cause of the error reported in #310: I was
worried that an address from the range occupied by the heap might
somehow be corrupted by the syscall variadic argument de-mangling, but
that looks like it is not the case.
2021-03-02 10:33:07 -05:00
Daniel Kahn Gillmor
a3f9410e51 Add clock_gettime_heap snippet
This invokes clock_gettime, but uses a timespec from the heap instead
of the stack.
2021-03-02 10:26:20 -05:00
Daniel Kahn Gillmor
a92d6ffe7c add snippet testing clock_gettime(CLOCK_REALTIME) 2021-03-02 10:23:11 -05:00
Daniel Kahn Gillmor
253774c8d8 added new simple snippet "time.c" 2021-03-01 21:47:18 -05:00
Daniel Kahn Gillmor
986e6e1cdc Clarify test/Makefile and snippet testing documentation
Hopefully this makes it easier for future development work to augment
the snippet-based testing.
2021-03-01 21:40:57 -05:00
Daniel Kahn Gillmor
0bfb72b627 tests: normalize "where" variable to include framework prefix and snippet name 2021-03-01 21:08:00 -05:00
Daniel Kahn Gillmor
5a1bd98979 parallelize library_contructors test 2021-03-01 21:05:22 -05:00
Daniel Kahn Gillmor
7e62881c8f Name "snippets" explicitly
Earlier, this code was conceived of to test a "function" specifically,
but some future snippet could test multiple function calls, or a
subset of a function call (e.g. snippets/syscall_clock_gettime.c
already only tests one particular syscall diversion number).

Normalizing on the name "snippet" should make it easier to understand
the code going forward.
2021-03-01 15:06:22 -05:00
Daniel Kahn Gillmor
940502b3de Added snippet for syscall(__NR_clock_gettime)
Closes: #176
2021-02-25 23:33:30 -05:00
Daniel Kahn Gillmor
26b4b395e9 Include a check for getentropy interception
This snippet applies to both the library constructors and variable
data test frameworks.
2021-02-25 23:17:25 -05:00
Daniel Kahn Gillmor
0b0cc29d2e test/randomtest.sh: avoid touching the filesystem 2021-02-25 23:17:25 -05:00
Daniel Kahn Gillmor
a5885f1479 Drop more duplicative tests
Now that we have the snippet-driven test_variable_data suite, most of
the other longer hand-written tests are duplicative.
2021-02-25 23:17:25 -05:00
Daniel Kahn Gillmor
0872c6c0c0 Add test_variable_data framework that reuses the snippets
Most of these snippets are likely to have some env var that causes the
data to hold constant, while the data will otherwise be likely to vary
over time.

This framework offers a way to test those snippets, by dropping the
variable and an example value in the test/snippets/FOO.variable
one-line file.

Note that the test/snippets/syscall.c snippet is *not* expected to
vary over time (or to differ when any given variable is set), so we
simply don't add any test/snippets/syscall.variable file to avoid it
being tested in this way.
2021-02-25 23:17:25 -05:00
Daniel Kahn Gillmor
f47223ff12 Include snippet for syscall() interception in library constructors 2021-02-25 23:17:25 -05:00
Daniel Kahn Gillmor
7b1d0958b5 Drop duplicate library constructor preload tests
These tests are already taken care of with the snippet-driven library
constructor tests.
2021-02-25 23:17:25 -05:00
Daniel Kahn Gillmor
17522c5ba1 Overhaul testing library constructors
We want to make it easier to test a bunch of different functions that
might be invoked in constructors of other libraries.

It seems conceivable that with these snippets, we could design other
tests that also work across a wide range of intercepted functions.
2021-02-25 23:17:25 -05:00
Daniel Kahn Gillmor
01f6bc76c9 clean up after syscall_test properly 2021-02-25 18:12:04 -05:00
Daniel Kahn Gillmor
f329eee8c5 Send test output to stdout, not stderr
debian autopkgtest instances (and maybe other test systems) will
report a failure if messages are sent to stderr.

Since these messages are diagnostic messages for the test suite, and
not indicators of actual failure, they should go to stdout, not
stderr.
2021-02-25 18:11:52 -05:00
Wolfgang Hommel
9337bccfcb Merge pull request #304 from dkg/cover-getentropy
better testing for interception of randomness from the kernel, including getentropy()
2021-02-25 06:27:35 +01:00
Daniel Kahn Gillmor
3db9d20828 Test getentropy
We want to ensure that tools that call getentropy() are also
controlled appropriately.
2021-02-24 16:03:57 -05:00
Daniel Kahn Gillmor
20e74b1b02 clean up randomtest.sh, make more flexible 2021-02-24 15:58:54 -05:00
Daniel Kahn Gillmor
00d6edf90c Test repeated invocations of getrandom()
A single program that invokes getrandom() repeatedly should end up
with the same stream of bytes, regardless of how it chunks up the
reading from the entropy source.

This test already passses.  I'm including it because it seems
like a useful confirmation.
2021-02-24 15:24:45 -05:00
Daniel Kahn Gillmor
811283e683 Intercept syscall
This is an attempt at an implementation to address #301.

Some things worth noting:

 - I am not particularly confident in my reverse of the variadic C
   ABI. While the code appears to work for me on x86_64, I could
   imagine some variations between platforms that I'm not
   understanding.

 - This works to intercept the invocation of syscall as seen in
   test/syscalltest.sh, as long as it was compiled with -DFAKE_RANDOM

 - defining -DINTERCEPT_SYSCALL on non-Linux platforms should result
   in a compile-time error.

 - This does *not* work to intercept the syscall sent by `openssl
   rand`, for some reason I don't yet understand.  Perhaps openssl has
   some platform-specific syscall mechanism that doesn't route them
   through libc's syscall() shim?
2021-02-24 14:45:38 -05:00