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.
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).
If FAKERANDOM is unset, we were still intercepting syscall() and
passing it through to clock_gettime, rather than letting it fall
through to real_syscall.
That would have the effect of diverting syscall(__NR_clock_gettime,…)
into the libc invocation of clock_gettime(…) (via real_clock_gettime).
While that probably does the same thing, it's probably a mistake to do
such a diversion when FAKETIME is unset.
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.
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.
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.
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.
I had to decide what to do if FAKE_PID wasn't defined during the
build. I decided that since the wrapper can't be sure it is preloading
the same library that it was built with (someone could somehow mix and
match the library and the wrapper tool), it should just warn and pass
along the value anyway.
This reserves the option space, but shouldn't annoy people too much if
they are running it on a system that doesn't have FAKE_PID enabled.
I note that this happens regardless of whether it is a "direct"
invocation or not. I don't fully understand all the tradeoffs here,
so I would appreciate another set of eyes reviewing this choice.
Closes: #308
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.
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.
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?
In some configurations, GNU make might treat librandom.so as an
ephemeral/intermediate build artifact and destroy it before
randomtest.sh is run. This ensures the shared object is present when
needed.