Skip to content

Commit

Permalink
Add regression test for user namespaces.
Browse files Browse the repository at this point in the history
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
  • Loading branch information
Blub committed Mar 5, 2018
1 parent 8a53d78 commit 84b1956
Show file tree
Hide file tree
Showing 14 changed files with 391 additions and 0 deletions.
2 changes: 2 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ AC_CONFIG_FILES([
tests/zfs-tests/callbacks/Makefile
tests/zfs-tests/cmd/Makefile
tests/zfs-tests/cmd/chg_usr_exec/Makefile
tests/zfs-tests/cmd/user_ns_exec/Makefile
tests/zfs-tests/cmd/devname2devid/Makefile
tests/zfs-tests/cmd/dir_rd_update/Makefile
tests/zfs-tests/cmd/file_check/Makefile
Expand Down Expand Up @@ -299,6 +300,7 @@ AC_CONFIG_FILES([
tests/zfs-tests/tests/functional/threadsappend/Makefile
tests/zfs-tests/tests/functional/tmpfile/Makefile
tests/zfs-tests/tests/functional/truncate/Makefile
tests/zfs-tests/tests/functional/user_namespace/Makefile
tests/zfs-tests/tests/functional/userquota/Makefile
tests/zfs-tests/tests/functional/upgrade/Makefile
tests/zfs-tests/tests/functional/vdev_zaps/Makefile
Expand Down
4 changes: 4 additions & 0 deletions tests/runfiles/linux.run
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,10 @@ tags = ['functional', 'truncate']
tests = ['upgrade_userobj_001_pos', 'upgrade_projectquota_001_pos']
tags = ['functional', 'upgrade']

[tests/functional/user_namespace]
tests = ['user_namespace_001']
tags = ['functional', 'user_namespace']

[tests/functional/userquota]
tests = [
'userquota_001_pos', 'userquota_002_pos', 'userquota_003_pos',
Expand Down
1 change: 1 addition & 0 deletions tests/zfs-tests/cmd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ EXTRA_DIST = file_common.h

SUBDIRS = \
chg_usr_exec \
user_ns_exec \
devname2devid \
dir_rd_update \
file_check \
Expand Down
1 change: 1 addition & 0 deletions tests/zfs-tests/cmd/user_ns_exec/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/user_ns_exec
6 changes: 6 additions & 0 deletions tests/zfs-tests/cmd/user_ns_exec/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include $(top_srcdir)/config/Rules.am

pkgexecdir = $(datadir)/@PACKAGE@/zfs-tests/bin

pkgexec_PROGRAMS = user_ns_exec
user_ns_exec_SOURCES = user_ns_exec.c
179 changes: 179 additions & 0 deletions tests/zfs-tests/cmd/user_ns_exec/user_ns_exec.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sched.h>

#define EXECSHELL "/bin/sh"
#define UIDMAP "0 100000 65536"

static int
child_main(int argc, char *argv[], int sync_pipe)
{
char sync_buf;
char cmds[BUFSIZ] = { 0 };
char sep[] = " ";
int i, len;

if (unshare(CLONE_NEWUSER | CLONE_NEWNS) != 0) {
perror("unshare");
return (1);
}

/* tell parent we entered the new namespace */
if (write(sync_pipe, "1", 1) != 1) {
perror("write");
return (1);
}

/* wait for parent to setup the uid mapping */
if (read(sync_pipe, &sync_buf, 1) != 1) {
(void) fprintf(stderr, "user namespace setup failed\n");
return (1);
}

close(sync_pipe);

if (setuid(0) != 0) {
perror("setuid");
return (1);
}
if (setgid(0) != 0) {
perror("setgid");
return (1);
}

len = 0;
for (i = 1; i < argc; i++) {
(void) snprintf(cmds+len, sizeof (cmds)-len,
"%s%s", argv[i], sep);
len += strlen(argv[i]) + strlen(sep);
}

if (execl(EXECSHELL, "sh", "-c", cmds, (char *)NULL) != 0) {
perror("execl: " EXECSHELL);
return (1);
}

return (0);
}

static int
set_idmap(pid_t pid, const char *file)
{
int result = 0;
int mapfd;
char path[PATH_MAX];

(void) snprintf(path, sizeof (path), "/proc/%d/%s", (int)pid, file);

mapfd = open(path, O_WRONLY);
if (mapfd < 0) {
result = errno;
perror("open");
return (errno);
}

if (write(mapfd, UIDMAP, sizeof (UIDMAP)-1) != sizeof (UIDMAP)-1) {
perror("write");
result = (errno);
}

close(mapfd);

return (result);
}

int
main(int argc, char *argv[])
{
char sync_buf;
int result, wstatus;
int syncfd[2];
pid_t child;

if (argc < 2 || strlen(argv[1]) == 0) {
(void) printf("\tUsage: %s <commands> ...\n", argv[0]);
return (1);
}

if (socketpair(AF_UNIX, SOCK_STREAM, 0, syncfd) != 0) {
perror("socketpair");
return (1);
}

child = fork();
if (child == (pid_t)-1) {
perror("fork");
return (1);
}

if (child == 0) {
close(syncfd[0]);
return (child_main(argc, argv, syncfd[1]));
}

close(syncfd[1]);

result = 0;
/* wait for the child to have unshared its namespaces */
if (read(syncfd[0], &sync_buf, 1) != 1) {
perror("read");
kill(child, SIGKILL);
result = 1;
goto reap;
}

/* write uid mapping */
if (set_idmap(child, "uid_map") != 0 ||
set_idmap(child, "gid_map") != 0) {
result = 1;
kill(child, SIGKILL);
goto reap;
}

/* tell the child to proceed */
if (write(syncfd[0], "1", 1) != 1) {
perror("write");
kill(child, SIGKILL);
result = 1;
goto reap;
}
close(syncfd[0]);

reap:
while (waitpid(child, &wstatus, 0) != child)
kill(child, SIGKILL);
if (result == 0)
result = WEXITSTATUS(wstatus);

return (result);
}
1 change: 1 addition & 0 deletions tests/zfs-tests/include/commands.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -171,4 +171,5 @@ export ZFSTEST_FILES='chg_usr_exec
rename_dir
rm_lnkcnt_zero_file
threadsappend
user_ns_exec
xattrtest'
1 change: 1 addition & 0 deletions tests/zfs-tests/tests/functional/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ SUBDIRS = \
tmpfile \
truncate \
upgrade \
user_namespace \
userquota \
vdev_zaps \
write_dirs \
Expand Down
7 changes: 7 additions & 0 deletions tests/zfs-tests/tests/functional/user_namespace/Makefile.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pkgdatadir = $(datadir)/@PACKAGE@/zfs-tests/tests/functional/user_namespace
dist_pkgdata_SCRIPTS = \
setup.ksh \
cleanup.ksh \
user_namespace_common.kshlib \
user_namespace.cfg \
user_namespace_001.ksh
25 changes: 25 additions & 0 deletions tests/zfs-tests/tests/functional/user_namespace/cleanup.ksh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

. $STF_SUITE/include/libtest.shlib

default_cleanup
32 changes: 32 additions & 0 deletions tests/zfs-tests/tests/functional/user_namespace/setup.ksh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/ksh -p
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

. $STF_SUITE/include/libtest.shlib

if ! [ -f /proc/self/uid_map ]; then
log_unsupported "The kernel doesn't support user namespaces."
fi

verify_runnable "both"

DISK=${DISKS%% *}
default_setup $DISK
23 changes: 23 additions & 0 deletions tests/zfs-tests/tests/functional/user_namespace/user_namespace.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#

export ROOT_UID=100000
export OTHER_UID=101000
Loading

0 comments on commit 84b1956

Please sign in to comment.