mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-09 23:00:07 +00:00
support: Add support_chroot_create and support_chroot_free
This commit is contained in:
parent
76637a921f
commit
d4165eedf5
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
|||||||
|
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>
|
2017-07-05 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
Add subtest to check isolation of multiple loopback addresses.
|
Add subtest to check isolation of multiple loopback addresses.
|
||||||
|
@ -47,46 +47,23 @@
|
|||||||
res_init. */
|
res_init. */
|
||||||
static const char *const test_hostname = "www.example.com";
|
static const char *const test_hostname = "www.example.com";
|
||||||
|
|
||||||
/* Path to the test root directory. */
|
struct support_chroot *chroot_env;
|
||||||
static char *path_chroot;
|
|
||||||
|
|
||||||
/* Path to resolv.conf under path_chroot (outside the chroot). */
|
|
||||||
static char *path_resolv_conf;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
prepare (int argc, char **argv)
|
prepare (int argc, char **argv)
|
||||||
{
|
{
|
||||||
path_chroot = xasprintf ("%s/tst-resolv-res_init-XXXXXX", test_dir);
|
chroot_env = support_chroot_create
|
||||||
if (mkdtemp (path_chroot) == NULL)
|
((struct support_chroot_configuration)
|
||||||
FAIL_EXIT1 ("mkdtemp (\"%s\"): %m", path_chroot);
|
{
|
||||||
add_temp_file (path_chroot);
|
.resolv_conf = "",
|
||||||
|
});
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Verify that the chroot environment has been set up. */
|
/* Verify that the chroot environment has been set up. */
|
||||||
static void
|
static void
|
||||||
check_chroot_working (void *closure)
|
check_chroot_working (void *closure)
|
||||||
{
|
{
|
||||||
xchroot (path_chroot);
|
xchroot (chroot_env->path_chroot);
|
||||||
FILE *fp = xfopen (_PATH_RESCONF, "r");
|
FILE *fp = xfopen (_PATH_RESCONF, "r");
|
||||||
xfclose (fp);
|
xfclose (fp);
|
||||||
|
|
||||||
@ -345,7 +322,7 @@ setup_nss_dns_and_chroot (void)
|
|||||||
/* Load nss_dns outside of the chroot. */
|
/* Load nss_dns outside of the chroot. */
|
||||||
if (dlopen (LIBNSS_DNS_SO, RTLD_LAZY) == NULL)
|
if (dlopen (LIBNSS_DNS_SO, RTLD_LAZY) == NULL)
|
||||||
FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ());
|
FAIL_EXIT1 ("could not load " LIBNSS_DNS_SO ": %s", dlerror ());
|
||||||
xchroot (path_chroot);
|
xchroot (chroot_env->path_chroot);
|
||||||
/* Force the use of nss_dns. */
|
/* Force the use of nss_dns. */
|
||||||
__nss_configure_lookup ("hosts", "dns");
|
__nss_configure_lookup ("hosts", "dns");
|
||||||
}
|
}
|
||||||
@ -374,13 +351,13 @@ run_res_init (void *closure)
|
|||||||
switch (ctx->init)
|
switch (ctx->init)
|
||||||
{
|
{
|
||||||
case test_init:
|
case test_init:
|
||||||
xchroot (path_chroot);
|
xchroot (chroot_env->path_chroot);
|
||||||
TEST_VERIFY (res_init () == 0);
|
TEST_VERIFY (res_init () == 0);
|
||||||
print_resp (stdout, &_res);
|
print_resp (stdout, &_res);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case test_ninit:
|
case test_ninit:
|
||||||
xchroot (path_chroot);
|
xchroot (chroot_env->path_chroot);
|
||||||
res_state resp = xmalloc (sizeof (*resp));
|
res_state resp = xmalloc (sizeof (*resp));
|
||||||
memset (resp, 0, sizeof (*resp));
|
memset (resp, 0, sizeof (*resp));
|
||||||
TEST_VERIFY (res_ninit (resp) == 0);
|
TEST_VERIFY (res_ninit (resp) == 0);
|
||||||
@ -390,7 +367,7 @@ run_res_init (void *closure)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case test_mkquery:
|
case test_mkquery:
|
||||||
xchroot (path_chroot);
|
xchroot (chroot_env->path_chroot);
|
||||||
unsigned char buf[512];
|
unsigned char buf[512];
|
||||||
TEST_VERIFY (res_mkquery (QUERY, "www.example",
|
TEST_VERIFY (res_mkquery (QUERY, "www.example",
|
||||||
C_IN, ns_t_a, NULL, 0,
|
C_IN, ns_t_a, NULL, 0,
|
||||||
@ -783,7 +760,7 @@ special_test_callback (void *closure)
|
|||||||
TEST_VERIFY (test_index < special_tests_count);
|
TEST_VERIFY (test_index < special_tests_count);
|
||||||
if (test_verbose > 0)
|
if (test_verbose > 0)
|
||||||
printf ("info: special test %u\n", test_index);
|
printf ("info: special test %u\n", test_index);
|
||||||
xchroot (path_chroot);
|
xchroot (chroot_env->path_chroot);
|
||||||
|
|
||||||
switch (test_index)
|
switch (test_index)
|
||||||
{
|
{
|
||||||
@ -1063,7 +1040,8 @@ do_test (void)
|
|||||||
TEST_VERIFY (test_cases[i].conf != NULL);
|
TEST_VERIFY (test_cases[i].conf != NULL);
|
||||||
TEST_VERIFY (test_cases[i].expected != 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]);
|
test_file_contents (&test_cases[i]);
|
||||||
|
|
||||||
@ -1073,24 +1051,24 @@ do_test (void)
|
|||||||
{
|
{
|
||||||
if (test_verbose > 0)
|
if (test_verbose > 0)
|
||||||
printf ("info: special test: missing file\n");
|
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]);
|
test_file_contents (&test_cases[i]);
|
||||||
|
|
||||||
if (test_verbose > 0)
|
if (test_verbose > 0)
|
||||||
printf ("info: special test: dangling symbolic link\n");
|
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_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)
|
if (test_verbose > 0)
|
||||||
printf ("info: special test: unreadable file\n");
|
printf ("info: special test: unreadable file\n");
|
||||||
support_write_file_string (path_resolv_conf, "");
|
support_write_file_string (chroot_env->path_resolv_conf, "");
|
||||||
TEST_VERIFY (chmod (path_resolv_conf, 0) == 0);
|
TEST_VERIFY (chmod (chroot_env->path_resolv_conf, 0) == 0);
|
||||||
test_file_contents (&test_cases[i]);
|
test_file_contents (&test_cases[i]);
|
||||||
|
|
||||||
/* Restore the empty file. */
|
/* Restore the empty file. */
|
||||||
TEST_VERIFY (unlink (path_resolv_conf) == 0);
|
TEST_VERIFY (unlink (chroot_env->path_resolv_conf) == 0);
|
||||||
support_write_file_string (path_resolv_conf, "");
|
support_write_file_string (chroot_env->path_resolv_conf, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1106,10 +1084,7 @@ do_test (void)
|
|||||||
xwaitpid (server, NULL, 0);
|
xwaitpid (server, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
free (path_chroot);
|
support_chroot_free (chroot_env);
|
||||||
path_chroot = NULL;
|
|
||||||
free (path_resolv_conf);
|
|
||||||
path_resolv_conf = NULL;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@ libsupport-routines = \
|
|||||||
support_can_chroot \
|
support_can_chroot \
|
||||||
support_capture_subprocess \
|
support_capture_subprocess \
|
||||||
support_capture_subprocess_check \
|
support_capture_subprocess_check \
|
||||||
|
support_chroot \
|
||||||
support_enter_network_namespace \
|
support_enter_network_namespace \
|
||||||
support_format_address_family \
|
support_format_address_family \
|
||||||
support_format_addrinfo \
|
support_format_addrinfo \
|
||||||
|
@ -60,6 +60,38 @@ bool support_in_uts_namespace (void);
|
|||||||
non-zero exit status. */
|
non-zero exit status. */
|
||||||
void support_isolate_in_subprocess (void (*callback) (void *), void *closure);
|
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
|
__END_DECLS
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
71
support/support_chroot.c
Normal file
71
support/support_chroot.c
Normal file
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user