From: Lucas De Marchi Date: Wed, 25 Jan 2012 04:44:45 +0000 (-0200) Subject: testsuite: add trap to fopen() including tests X-Git-Tag: v5~68 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6afc9cd616f792deafc9d5d1ee3cd7edd5d90ce2;p=thirdparty%2Fkmod.git testsuite: add trap to fopen() including tests --- diff --git a/Makefile.am b/Makefile.am index 47664240..6e9a45d2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,6 @@ SUBDIRS = . libkmod/docs man +DISTCLEAN_LOCAL_HOOKS = EXTRA_DIST = CLEANFILES = ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} @@ -128,6 +129,10 @@ ${noinst_SCRIPTS}: tools/kmod-nolib $(LN_S) $(notdir $<) $@) endif +# ------------------------------------------------------------------------------ +# TESTSUITE +# ------------------------------------------------------------------------------ + # libtool will not create a shared library that is not installed. Workaround # this by creating it by ourselves CREATE_SHARED_OVERRIDE_LIB = \ @@ -137,13 +142,30 @@ CREATE_SHARED_OVERRIDE_LIB = \ testsuite/uname.so: testsuite/uname.c $(CREATE_SHARED_OVERRIDE_LIB) -EXTRA_DIST += testsuite/uname.c -CLEANFILES += testsuite/uname.so +testsuite/path.so: testsuite/path.c + $(CREATE_SHARED_OVERRIDE_LIB) + +EXTRA_DIST += testsuite/uname.c testsuite/path.c +CLEANFILES += testsuite/uname.so testsuite/path.so + +testsuite/rootfs: + $(AM_V_GEN) tar -C testsuite/ \ + -xJf $(top_srcdir)/testsuite/rootfs.tar.xz + +testsuite-distclean: + -rm -rf testsuite/rootfs + +DISTCLEAN_LOCAL_HOOKS += testsuite-distclean +EXTRA_DIST += testsuite/rootfs.tar.xz check_LTLIBRARIES = testsuite/libtestsuite.la testsuite_libtestsuite_la_SOURCES = testsuite/testsuite.c \ testsuite/testsuite.h -testsuite_libtestsuite_la_DEPENDENCIES = testsuite/uname.so +testsuite_libtestsuite_la_DEPENDENCIES = testsuite/uname.so \ + testsuite/path.so \ + testsuite/rootfs +testsuite_test_testsuite_CPPFLAGS = $(AM_CPPFLAGS) \ + -DTESTSUITE_ROOTFS=\"$(abs_top_builddir)/testsuite/rootfs/\" TESTSUITE = testsuite/test-init testsuite/test-testsuite check_PROGRAMS = $(TESTSUITE) @@ -154,6 +176,7 @@ testsuite_test_testsuite_LDADD = testsuite/libtestsuite.la DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc +distclean-local: $(DISTCLEAN_LOCAL_HOOKS) # ------------------------------------------------------------------------------ # custom release helpers diff --git a/testsuite/.gitignore b/testsuite/.gitignore index 4b5d6967..2cd9099e 100644 --- a/testsuite/.gitignore +++ b/testsuite/.gitignore @@ -4,3 +4,4 @@ *.so test-testsuite test-init +rootfs/ diff --git a/testsuite/path.c b/testsuite/path.c new file mode 100644 index 00000000..9b435b49 --- /dev/null +++ b/testsuite/path.c @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "testsuite.h" + +static void *nextlib; +static const char *rootpath; +static size_t rootpathlen; + +static inline bool need_trap(const char *path) +{ + return path != NULL && path[0] == '/'; +} + +static const char *trap_path(const char *path, char buf[PATH_MAX * 2]) +{ + size_t len; + + if (!need_trap(path)) + return path; + + len = strlen(path); + + if (len + rootpathlen > PATH_MAX * 2) { + errno = ENAMETOOLONG; + return NULL; + } + + memcpy(buf, rootpath, rootpathlen); + strcpy(buf + rootpathlen, path); + return buf; +} + +static bool get_rootpath(const char *f) +{ + if (rootpath != NULL) + return true; + + rootpath = getenv(S_TC_ROOTFS); + if (rootpath == NULL) { + ERR("TRAP %s(): missing export %s?\n", f, S_TC_ROOTFS); + errno = ENOENT; + return false; + } + + rootpathlen = strlen(rootpath); + + return true; +} + +static void *get_libc_func(const char *f) +{ + void *fp; + + if (nextlib == NULL) { +#ifdef RTLD_NEXT + nextlib = RTLD_NEXT; +#else + nextlib = dlopen("libc.so.6", RTLD_LAZY); +#endif + } + + fp = dlsym(nextlib, f); + assert(fp); + + return fp; +} + +TS_EXPORT FILE *fopen(const char *path, const char *mode) +{ + const char *p; + char buf[PATH_MAX * 2]; + static int (*_fopen)(const char *path, const char *mode); + + if (!get_rootpath(__func__)) + return NULL; + + _fopen = get_libc_func("fopen"); + + p = trap_path(path, buf); + if (p == NULL) + return NULL; + + return (void *) (long) (*_fopen)(p, mode); +} diff --git a/testsuite/rootfs.tar.xz b/testsuite/rootfs.tar.xz new file mode 100644 index 00000000..233caeb4 Binary files /dev/null and b/testsuite/rootfs.tar.xz differ diff --git a/testsuite/test-testsuite.c b/testsuite/test-testsuite.c index edbfe45c..f5b6fceb 100644 --- a/testsuite/test-testsuite.c +++ b/testsuite/test-testsuite.c @@ -38,8 +38,38 @@ static const struct test stestsuite_uname = { .need_spawn = true, }; +static int testsuite_rootfs_fopen(const struct test *t) +{ + FILE *fp; + char s[100]; + int n; + + fp = fopen("/lib/modules/a", "r"); + if (fp == NULL) + return EXIT_FAILURE;; + + n = fscanf(fp, "%s", s); + if (n != 1) + return EXIT_FAILURE; + + if (strcmp(s, "kmod-test-chroot-works") != 0) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} +static const struct test stestsuite_rootfs_fopen = { + .name = "testsuite_rootfs_fopen", + .description = "test if rootfs works - fopen()", + .func = testsuite_rootfs_fopen, + .config = { + [TC_ROOTFS] = TESTSUITE_ROOTFS "test-rootfs/", + }, + .need_spawn = true, +}; + static const struct test *tests[] = { &stestsuite_uname, + &stestsuite_rootfs_fopen, NULL, }; diff --git a/testsuite/testsuite.h b/testsuite/testsuite.h index 669b9d70..e06ecf2d 100644 --- a/testsuite/testsuite.h +++ b/testsuite/testsuite.h @@ -13,6 +13,7 @@ enum test_config { _TC_LAST, }; +#define S_TC_ROOTFS "TESTSUITE_ROOTFS" #define S_TC_UNAME_R "TESTSUITE_UNAME_R"