summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>2021-02-25 14:07:17 -0500
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>2021-02-25 23:17:25 -0500
commit17522c5ba124c5941e2cd3832a68722d64c6bf4b (patch)
treecdf572286861a1cf1df49a3fa4a06a400259bd5c
parent01f6bc76c9613db70c3ef41c2c62ae3fc8d2d431 (diff)
downloadlibfaketime-17522c5ba124c5941e2cd3832a68722d64c6bf4b.tar.gz
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.
-rw-r--r--.gitignore4
-rw-r--r--test/Makefile24
-rw-r--r--test/_libtest.c8
-rw-r--r--test/_use_lib_test.c7
-rw-r--r--test/libgetpid.c13
-rw-r--r--test/libgetpid.h6
-rw-r--r--test/librandom.c17
-rw-r--r--test/librandom.h6
-rwxr-xr-xtest/randomtest.sh6
-rw-r--r--test/snippets/README32
-rw-r--r--test/snippets/getpid.c2
-rw-r--r--test/snippets/getrandom.c7
-rw-r--r--test/snippets/include_headers.h4
-rwxr-xr-xtest/test_constructors.sh10
-rw-r--r--test/use_lib_getpid.c12
-rw-r--r--test/use_lib_random.c6
16 files changed, 90 insertions, 74 deletions
diff --git a/.gitignore b/.gitignore
index 7310425..80a2439 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,10 +2,8 @@
*.so.1
timetest
test/getrandom_test
-test/lib*.o
test/lib*.so
-test/use_lib_random
-test/use_lib_getpid
+test/use_lib_*
test/repeat_random
test/getentropy_test
test/syscall_test
diff --git a/test/Makefile b/test/Makefile
index e19a7bc..aed85a5 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -6,6 +6,8 @@ LDFLAGS = -lrt -lpthread
SRC = timetest.c
OBJ = ${SRC:.c=.o}
+TESTFUNCS = $(notdir $(basename $(wildcard snippets/*.c)))
+
all: timetest test
.c.o:
@@ -25,7 +27,7 @@ functest:
%_test: %_test.c
${CC} -o $@ ${CFLAGS} $<
-randomtest: getrandom_test use_lib_random librandom.so repeat_random getentropy_test
+randomtest: getrandom_test use_lib_getrandom libgetrandom.so repeat_random getentropy_test
./randomtest.sh
getpidtest: use_lib_getpid libgetpid.so
@@ -34,17 +36,23 @@ getpidtest: use_lib_getpid libgetpid.so
syscalltest: syscall_test
./syscalltest.sh
-lib%.o: lib%.c
- ${CC} -c -o $@ -fpic ${CFLAGS} $<
-lib%.so: lib%.o
- ${CC} -o $@ -shared ${CFLAGS} $<
+## testing when interception points get called in library constructors:
+
+test_library_constructors: test_constructors.sh $(foreach f,${TESTFUNCS},use_lib_${f} lib${f}.so)
+ true $(foreach f,${TESTFUNCS},&& ./test_constructors.sh ${f})
+
+lib%.so: _libtest.c snippets/%.c
+ sed s/FUNC_NAME/$*/g < _libtest.c | ${CC} -shared -o $@ -fpic ${CFLAGS} -x c -
+
+use_lib_%: _use_lib_test.c snippets/%.c lib%.so
+ sed s/FUNC_NAME/$*/g < _use_lib_test.c | ${CC} -L. -o $@ ${CFLAGS} -x c - -l$*
+
-use_lib_%: use_lib_%.c lib%.so
- ${CC} -L. -o $@ ${CFLAGS} $< -l$*
+## cleanup and metainformation
clean:
- @rm -f ${OBJ} timetest getrandom_test lib*.o lib*.so use_lib_random use_lib_getpid syscall_test
+ @rm -f ${OBJ} timetest getrandom_test syscall_test $(foreach f,${TESTFUNCS},use_lib_${f} lib${f}.so)
distclean: clean
@echo
diff --git a/test/_libtest.c b/test/_libtest.c
new file mode 100644
index 0000000..2fa0bc9
--- /dev/null
+++ b/test/_libtest.c
@@ -0,0 +1,8 @@
+#include "snippets/include_headers.h"
+#define where "library"
+void FUNC_NAME_as_needed() {
+ printf(" called FUNC_NAME_as_needed() \n");
+}
+static __attribute__((constructor)) void init_FUNC_NAME() {
+#include "snippets/FUNC_NAME.c"
+}
diff --git a/test/_use_lib_test.c b/test/_use_lib_test.c
new file mode 100644
index 0000000..24d8cc7
--- /dev/null
+++ b/test/_use_lib_test.c
@@ -0,0 +1,7 @@
+#include "snippets/include_headers.h"
+extern void FUNC_NAME_as_needed();
+#define where "program"
+int main() {
+ FUNC_NAME_as_needed();
+#include "snippets/FUNC_NAME.c"
+}
diff --git a/test/libgetpid.c b/test/libgetpid.c
deleted file mode 100644
index fce94ce..0000000
--- a/test/libgetpid.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-void getpid_func() {
- printf(" called getpid_func()\n");
-}
-
-
-static __attribute__((constructor)) void getpid_init() {
- pid_t pid = getpid();
- printf(" getpid() yielded %d\n", pid);
-}
diff --git a/test/libgetpid.h b/test/libgetpid.h
deleted file mode 100644
index e18c61d..0000000
--- a/test/libgetpid.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __LIBGETPID_H__
-#define __LIBGETPID_H__
-
-extern void getpid_func();
-
-#endif
diff --git a/test/librandom.c b/test/librandom.c
deleted file mode 100644
index 8152776..0000000
--- a/test/librandom.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <stdio.h>
-#include <sys/random.h>
-
-void func() {
- printf(" called func()\n");
-}
-
-
-static __attribute__((constructor)) void rnd_init() {
- unsigned int targ;
- ssize_t ret = getrandom(&targ, sizeof(targ), 0);
- if (ret == sizeof(targ)) {
- printf(" getrandom() yielded 0x%08x\n", targ);
- } else {
- printf(" getrandom() failed with only %zd\n", ret);
- }
-}
diff --git a/test/librandom.h b/test/librandom.h
deleted file mode 100644
index 9037fce..0000000
--- a/test/librandom.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __LIBRANDOM_H__
-#define __LIBRANDOM_H__
-
-extern void func();
-
-#endif
diff --git a/test/randomtest.sh b/test/randomtest.sh
index 4055188..1ba86e3 100755
--- a/test/randomtest.sh
+++ b/test/randomtest.sh
@@ -35,12 +35,12 @@ for iface in getrandom getentropy; do
done
printf 'testing shared object with getrandom() in library constructor\n'
-LD_LIBRARY_PATH=. ./use_lib_random
+LD_LIBRARY_PATH=. ./use_lib_getrandom
printf 'now with LD_PRELOAD and FAKERANDOM_SEED\n'
-FAKERANDOM_SEED=0x0000000000000000 LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_random
+FAKERANDOM_SEED=0x0000000000000000 LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_getrandom
# this demonstrates the crasher from https://github.com/wolfcw/libfaketime/issues/295
printf 'now with LD_PRELOAD without FAKERANDOM_SEED\n'
-LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_random
+LD_PRELOAD="$FTPL" LD_LIBRARY_PATH=. ./use_lib_getrandom
FAKERANDOM_SEED=0xDEADBEEFDEADBEEF LD_PRELOAD="$FTPL" ./repeat_random 3 5 > repeat3x5
diff --git a/test/snippets/README b/test/snippets/README
new file mode 100644
index 0000000..665004d
--- /dev/null
+++ b/test/snippets/README
@@ -0,0 +1,32 @@
+Bulk testing of function interception
+=====================================
+
+Faketime intercepts some C library functions. We want to make it
+easier to apply certain generic tests across many different functions.
+
+Including a new function
+------------------------
+
+To test a function FOO, supply a C snippet in this directory named
+<FOO.c>. This should be a small bit of code that exercises the
+function FOO. It should be self-contained, and it should produce some
+kind of description of what happened to stdout. Take a look at
+getpid.c for a simple example.
+
+The data sent to stdout should include the const char* "where" value
+(which is an indication of which test framework is using the snippet).
+And it should ideally be stable when the associated variable
+(e.g. FAKETIME, FAKETIME_FAKEPID, or FAKERANDOM_SEED) is set, and
+likely to vary otherwise, especially across a delay of a second or
+more.
+
+If the snippet needs to additional #include headers, please add them
+in include_headers.h. These #includes will be used by every snippet,
+so try to keep it minimal.
+
+Testing across functions
+------------------------
+
+If you want to test something systemically, autogenerate code that
+uses each snippet. See test_library_constructors in ../Makefile for
+an example.
diff --git a/test/snippets/getpid.c b/test/snippets/getpid.c
new file mode 100644
index 0000000..695d3db
--- /dev/null
+++ b/test/snippets/getpid.c
@@ -0,0 +1,2 @@
+pid_t pid = getpid();
+printf("[%s] getpid() yielded %d\n", where, pid);
diff --git a/test/snippets/getrandom.c b/test/snippets/getrandom.c
new file mode 100644
index 0000000..03b0980
--- /dev/null
+++ b/test/snippets/getrandom.c
@@ -0,0 +1,7 @@
+unsigned int targ;
+ssize_t ret = getrandom(&targ, sizeof(targ), 0);
+if (ret == sizeof(targ)) {
+ printf("[%s] getrandom() yielded 0x%08x\n", where, targ);
+} else {
+ printf("[%s] getrandom() failed with only %zd\n", where, ret);
+}
diff --git a/test/snippets/include_headers.h b/test/snippets/include_headers.h
new file mode 100644
index 0000000..b9b8040
--- /dev/null
+++ b/test/snippets/include_headers.h
@@ -0,0 +1,4 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/random.h>
diff --git a/test/test_constructors.sh b/test/test_constructors.sh
new file mode 100755
index 0000000..5a628c4
--- /dev/null
+++ b/test/test_constructors.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
+
+function="$1"
+
+printf 'Testing library init for %s (no LD_PRELOAD)\n' "$function"
+LD_LIBRARY_PATH=. "./use_lib_$function"
+printf 'Testing library init for %s (LD_PRELOAD)\n' "$function"
+LD_LIBRARY_PATH=. LD_PRELOAD="$FTPL" "./use_lib_$function"
diff --git a/test/use_lib_getpid.c b/test/use_lib_getpid.c
deleted file mode 100644
index f9b5d94..0000000
--- a/test/use_lib_getpid.c
+++ /dev/null
@@ -1,12 +0,0 @@
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include "libgetpid.h"
-
-int main() {
- pid_t pid;
- getpid_func();
- pid = getpid();
- printf(" getpid() -> %d\n", pid);
- return 0;
-}
diff --git a/test/use_lib_random.c b/test/use_lib_random.c
deleted file mode 100644
index 583608d..0000000
--- a/test/use_lib_random.c
+++ /dev/null
@@ -1,6 +0,0 @@
-#include "librandom.h"
-
-int main() {
- func();
- return 0;
-}