1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-10 05:03:06 +03:00

test-container: add "su" command to run test as root, add unshare hints

* support/test-container.c (check_for_unshare_hints): New.
(main): Call it if unshare fails.  Add support for "su" scriptlet
command.
This commit is contained in:
DJ Delorie
2018-12-04 00:03:12 -05:00
parent 477a02f637
commit b2e93de0ff
2 changed files with 70 additions and 4 deletions

View File

@@ -1,3 +1,9 @@
2018-12-03 DJ Delorie <dj@delorie.com>
* support/test-container.c (check_for_unshare_hints): New.
(main): Call it if unshare fails. Add support for "su" scriptlet
command.
2018-12-03 Joseph Myers <joseph@codesourcery.com> 2018-12-03 Joseph Myers <joseph@codesourcery.com>
* scripts/gen-as-const.py (compute_c_consts): Take an argument * scripts/gen-as-const.py (compute_c_consts): Take an argument

View File

@@ -88,15 +88,22 @@ int verbose = 0;
* mytest.root/ is rsync'd into container * mytest.root/ is rsync'd into container
* mytest.root/preclean.req causes fresh rsync (with delete) before * mytest.root/preclean.req causes fresh rsync (with delete) before
test if present test if present
* mytest.root/mytset.script has a list of "commands" to run: * mytest.root/mytest.script has a list of "commands" to run:
syntax: syntax:
# comment # comment
su
mv FILE FILE mv FILE FILE
cp FILE FILE cp FILE FILE
rm FILE rm FILE
FILE must start with $B/, $S/, $I/, $L/, or / FILE must start with $B/, $S/, $I/, $L/, or /
(expands to build dir, source dir, install dir, library dir (expands to build dir, source dir, install dir, library dir
(in container), or container's root) (in container), or container's root)
details:
- '#': A comment.
- 'su': Enables running test as root in the container.
- 'mv': A minimal move files command.
- 'cp': A minimal copy files command.
- 'rm': A minimal remove files command.
* mytest.root/postclean.req causes fresh rsync (with delete) after * mytest.root/postclean.req causes fresh rsync (with delete) after
test if present test if present
@@ -349,6 +356,7 @@ recursive_remove (char *path)
switch (child) { switch (child) {
case -1: case -1:
perror("fork");
FAIL_EXIT1 ("Unable to fork"); FAIL_EXIT1 ("Unable to fork");
case 0: case 0:
/* Child. */ /* Child. */
@@ -610,6 +618,47 @@ rsync (char *src, char *dest, int and_delete)
} }
/* See if we can detect what the user needs to do to get unshare
support working for us. */
void
check_for_unshare_hints (void)
{
FILE *f;
int i;
/* Default Debian Linux disables user namespaces, but allows a way
to enable them. */
f = fopen ("/proc/sys/kernel/unprivileged_userns_clone", "r");
if (f != NULL)
{
i = 99; /* Sentinel. */
fscanf (f, "%d", &i);
if (i == 0)
{
printf ("To enable test-container, please run this as root:\n");
printf (" echo 1 > /proc/sys/kernel/unprivileged_userns_clone\n");
}
fclose (f);
return;
}
/* ALT Linux has an alternate way of doing the same. */
f = fopen ("/proc/sys/kernel/userns_restrict", "r");
if (f != NULL)
{
i = 99; /* Sentinel. */
fscanf (f, "%d", &i);
if (i == 1)
{
printf ("To enable test-container, please run this as root:\n");
printf (" echo 0 > /proc/sys/kernel/userns_restrict\n");
}
fclose (f);
return;
}
}
int int
main (int argc, char **argv) main (int argc, char **argv)
{ {
@@ -628,6 +677,8 @@ main (int argc, char **argv)
uid_t original_uid; uid_t original_uid;
gid_t original_gid; gid_t original_gid;
/* If set, the test runs as root instead of the user running the testsuite. */
int be_su = 0;
int UMAP; int UMAP;
int GMAP; int GMAP;
/* Used for "%lld %lld 1" so need not be large. */ /* Used for "%lld %lld 1" so need not be large. */
@@ -857,6 +908,10 @@ main (int argc, char **argv)
{ {
maybe_xunlink (the_words[1]); maybe_xunlink (the_words[1]);
} }
else if (nt == 1 && strcmp (the_words[0], "su") == 0)
{
be_su = 1;
}
else if (nt > 0 && the_words[0][0] != '#') else if (nt > 0 && the_words[0][0] != '#')
{ {
printf ("\033[31minvalid [%s]\033[0m\n", the_words[0]); printf ("\033[31minvalid [%s]\033[0m\n", the_words[0]);
@@ -873,7 +928,12 @@ main (int argc, char **argv)
/* Older kernels may not support all the options, or security /* Older kernels may not support all the options, or security
policy may block this call. */ policy may block this call. */
if (errno == EINVAL || errno == EPERM) if (errno == EINVAL || errno == EPERM)
FAIL_UNSUPPORTED ("unable to unshare user/fs: %s", strerror (errno)); {
int saved_errno = errno;
if (errno == EPERM)
check_for_unshare_hints ();
FAIL_UNSUPPORTED ("unable to unshare user/fs: %s", strerror (saved_errno));
}
else else
FAIL_EXIT1 ("unable to unshare user/fs: %s", strerror (errno)); FAIL_EXIT1 ("unable to unshare user/fs: %s", strerror (errno));
} }
@@ -952,7 +1012,7 @@ main (int argc, char **argv)
FAIL_EXIT1 ("can't write to /proc/self/uid_map\n"); FAIL_EXIT1 ("can't write to /proc/self/uid_map\n");
sprintf (tmp, "%lld %lld 1\n", sprintf (tmp, "%lld %lld 1\n",
(long long) original_uid, (long long) original_uid); (long long) (be_su ? 0 : original_uid), (long long) original_uid);
write (UMAP, tmp, strlen (tmp)); write (UMAP, tmp, strlen (tmp));
xclose (UMAP); xclose (UMAP);
@@ -973,7 +1033,7 @@ main (int argc, char **argv)
FAIL_EXIT1 ("can't write to /proc/self/gid_map\n"); FAIL_EXIT1 ("can't write to /proc/self/gid_map\n");
sprintf (tmp, "%lld %lld 1\n", sprintf (tmp, "%lld %lld 1\n",
(long long) original_gid, (long long) original_gid); (long long) (be_su ? 0 : original_gid), (long long) original_gid);
write (GMAP, tmp, strlen (tmp)); write (GMAP, tmp, strlen (tmp));
xclose (GMAP); xclose (GMAP);