diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | resolv/tst-resolv-res_init-skeleton.c | 69 | ||||
-rw-r--r-- | support/Makefile | 1 | ||||
-rw-r--r-- | support/namespace.h | 32 | ||||
-rw-r--r-- | support/support_chroot.c | 71 |
5 files changed, 140 insertions, 47 deletions
diff --git a/ChangeLog b/ChangeLog index 42ffe74254..5cbeb7b89c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,19 @@ 2017-07-05 Florian Weimer <fweimer@redhat.com> + * support/namespace.h (struct support_chroot_configuration) + (struct support_chroot): Define. + (support_chroot_create, support_chroot_free): New functions. + * support/support_chroot.c: New file. + * support/Makefile (libsupport-routines): Add support_chroot. + * resolv/tst-resolv-res_init-skeleton.c (path_chroot) + (path_resolv_conf): Remove definitions. + (chroot_env): New variable. + (prepare): Call support_chroot_create. + (check_chroot_working, setup_nss_dns_and_chroot, run_res_init) + (special_test_callback, do_test): Likewise. + +2017-07-05 Florian Weimer <fweimer@redhat.com> + Add subtest to check isolation of multiple loopback addresses. * support/tst-support-namespace.c (test_localhost_bind): New function. (do_test): Call it. diff --git a/resolv/tst-resolv-res_init-skeleton.c b/resolv/tst-resolv-res_init-skeleton.c index 8f395d8ce9..3b7b4129e3 100644 --- a/resolv/tst-resolv-res_init-skeleton.c +++ b/resolv/tst-resolv-res_init-skeleton.c @@ -47,46 +47,23 @@ res_init. */ static const char *const test_hostname = "www.example.com"; -/* Path to the test root directory. */ -static char *path_chroot; - -/* Path to resolv.conf under path_chroot (outside the chroot). */ -static char *path_resolv_conf; +struct support_chroot *chroot_env; static void prepare (int argc, char **argv) { - path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir); - if (mkdtemp (path_chroot) == NULL) - FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", path_chroot); - add_temp_file (path_chroot); - - /* Create the /etc directory in the chroot environment. */ - char *path_etc = xasprintf ("%s/etc", path_chroot); - xmkdir (path_etc, 0777); - add_temp_file (path_etc); - - /* Create an empty resolv.conf file. */ - path_resolv_conf = xasprintf ("%s/resolv.conf", path_etc); - add_temp_file (path_resolv_conf); - support_write_file_string (path_resolv_conf, ""); - - free (path_etc); - - /* valgrind needs a temporary directory in the chroot. */ - { - char *path_tmp = xasprintf ("%s/tmp", path_chroot); - xmkdir (path_tmp, 0777); - add_temp_file (path_tmp); - free (path_tmp); - } + chroot_env = support_chroot_create + ((struct support_chroot_configuration) + { + .resolv_conf = "", + }); } /* Verify that the chroot environment has been set up. */ static void check_chroot_working (void *closure) { - xchroot (path_chroot); + xchroot (chroot_env->path_chroot); FILE *fp = xfopen (_PATH_RESCONF, "r"); xfclose (fp); @@ -345,7 +322,7 @@ setup_nss_dns_and_chroot (void) /* Load nss_dns outside of the chroot. */ if (dlopen (LIBNSS_DNS_SO, RTLD_LAZY) == NULL) FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ()); - xchroot (path_chroot); + xchroot (chroot_env->path_chroot); /* Force the use of nss_dns. */ __nss_configure_lookup ("hosts", "dns"); } @@ -374,13 +351,13 @@ run_res_init (void *closure) switch (ctx->init) { case test_init: - xchroot (path_chroot); + xchroot (chroot_env->path_chroot); TEST_VERIFY (res_init () == 0); print_resp (stdout, &_res); return; case test_ninit: - xchroot (path_chroot); + xchroot (chroot_env->path_chroot); res_state resp = xmalloc (sizeof (*resp)); memset (resp, 0, sizeof (*resp)); TEST_VERIFY (res_ninit (resp) == 0); @@ -390,7 +367,7 @@ run_res_init (void *closure) return; case test_mkquery: - xchroot (path_chroot); + xchroot (chroot_env->path_chroot); unsigned char buf[512]; TEST_VERIFY (res_mkquery (QUERY, "www.example", C_IN, ns_t_a, NULL, 0, @@ -783,7 +760,7 @@ special_test_callback (void *closure) TEST_VERIFY (test_index < special_tests_count); if (test_verbose > 0) printf ("info: special test %u\n", test_index); - xchroot (path_chroot); + xchroot (chroot_env->path_chroot); switch (test_index) { @@ -1063,7 +1040,8 @@ do_test (void) TEST_VERIFY (test_cases[i].conf != NULL); TEST_VERIFY (test_cases[i].expected != NULL); - support_write_file_string (path_resolv_conf, test_cases[i].conf); + support_write_file_string (chroot_env->path_resolv_conf, + test_cases[i].conf); test_file_contents (&test_cases[i]); @@ -1073,24 +1051,24 @@ do_test (void) { if (test_verbose > 0) printf ("info: special test: missing file\n"); - TEST_VERIFY (unlink (path_resolv_conf) == 0); + TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0); test_file_contents (&test_cases[i]); if (test_verbose > 0) printf ("info: special test: dangling symbolic link\n"); - TEST_VERIFY (symlink ("does-not-exist", path_resolv_conf) == 0); + TEST_VERIFY (symlink ("does-not-exist", chroot_env->path_resolv_conf) == 0); test_file_contents (&test_cases[i]); - TEST_VERIFY (unlink (path_resolv_conf) == 0); + TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0); if (test_verbose > 0) printf ("info: special test: unreadable file\n"); - support_write_file_string (path_resolv_conf, ""); - TEST_VERIFY (chmod (path_resolv_conf, 0) == 0); + support_write_file_string (chroot_env->path_resolv_conf, ""); + TEST_VERIFY (chmod (chroot_env->path_resolv_conf, 0) == 0); test_file_contents (&test_cases[i]); /* Restore the empty file. */ - TEST_VERIFY (unlink (path_resolv_conf) == 0); - support_write_file_string (path_resolv_conf, ""); + TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0); + support_write_file_string (chroot_env->path_resolv_conf, ""); } } @@ -1106,10 +1084,7 @@ do_test (void) xwaitpid (server, NULL, 0); } - free (path_chroot); - path_chroot = NULL; - free (path_resolv_conf); - path_resolv_conf = NULL; + support_chroot_free (chroot_env); return 0; } diff --git a/support/Makefile b/support/Makefile index 423538d06a..1eba34b749 100644 --- a/support/Makefile +++ b/support/Makefile @@ -40,6 +40,7 @@ libsupport-routines = \ support_can_chroot \ support_capture_subprocess \ support_capture_subprocess_check \ + support_chroot \ support_enter_network_namespace \ support_format_address_family \ support_format_addrinfo \ diff --git a/support/namespace.h b/support/namespace.h index e1ccaa1ef0..859c2fda3f 100644 --- a/support/namespace.h +++ b/support/namespace.h @@ -60,6 +60,38 @@ bool support_in_uts_namespace (void); non-zero exit status. */ void support_isolate_in_subprocess (void (*callback) (void *), void *closure); +/* Describe the setup of a chroot environment, for + support_chroot_create below. */ +struct support_chroot_configuration +{ + /* File contents. The files are not created if the field is + NULL. */ + const char *resolv_conf; +}; + +/* The result of the creation of a chroot. */ +struct support_chroot +{ + /* Path information. All these paths are relative to the parent + chroot. */ + + /* Path to the chroot directory. */ + char *path_chroot; + + /* Path to the /etc/resolv.conf file. */ + char *path_resolv_conf; +}; + +/* Create a chroot environment. The returned data should be freed + using support_chroot_free below. The files will be deleted when + the process exits. This function does not enter the chroot. */ +struct support_chroot *support_chroot_create + (struct support_chroot_configuration); + +/* Deallocate the chroot information created by + support_chroot_create. */ +void support_chroot_free (struct support_chroot *); + __END_DECLS #endif diff --git a/support/support_chroot.c b/support/support_chroot.c new file mode 100644 index 0000000000..c0807b313a --- /dev/null +++ b/support/support_chroot.c @@ -0,0 +1,71 @@ +/* Setup a chroot environment for use within tests. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdlib.h> +#include <support/check.h> +#include <support/namespace.h> +#include <support/support.h> +#include <support/temp_file.h> +#include <support/test-driver.h> +#include <support/xunistd.h> + +struct support_chroot * +support_chroot_create (struct support_chroot_configuration conf) +{ + struct support_chroot *chroot = xmalloc (sizeof (*chroot)); + + chroot->path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir); + if (mkdtemp (chroot->path_chroot) == NULL) + FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", chroot->path_chroot); + add_temp_file (chroot->path_chroot); + + /* Create the /etc directory in the chroot environment. */ + char *path_etc = xasprintf ("%s/etc", chroot->path_chroot); + xmkdir (path_etc, 0777); + add_temp_file (path_etc); + + if (conf.resolv_conf != NULL) + { + /* Create an empty resolv.conf file. */ + chroot->path_resolv_conf = xasprintf ("%s/resolv.conf", path_etc); + add_temp_file (chroot->path_resolv_conf); + support_write_file_string (chroot->path_resolv_conf, conf.resolv_conf); + } + else + chroot->path_resolv_conf = NULL; + + free (path_etc); + + /* valgrind needs a temporary directory in the chroot. */ + { + char *path_tmp = xasprintf ("%s/tmp", chroot->path_chroot); + xmkdir (path_tmp, 0777); + add_temp_file (path_tmp); + free (path_tmp); + } + + return chroot; +} + +void +support_chroot_free (struct support_chroot *chroot) +{ + free (chroot->path_chroot); + free (chroot->path_resolv_conf); + free (chroot); +} |