• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/sh
2#
3# Copyright (c) 2017 FUJITSU LIMITED. All rights reserved.
4# Author: Xiao Yang <yangx.jy@cn.fujitsu.com>
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14# the GNU General Public License for more details.
15#
16# Test unshare command with some basic options.
17# 1) If we run unshare with "--user", UID in the newly created user namespace
18#    is set to 65534.
19# 2) If we run unshare with "--user", GID in the newly created user namespace
20#    is set to 65534.
21# 3) If we run with "--user --map-root-user", UID in the newly created user
22#    namespace is set to 0.
23# 4) If we run with "--user --map-root-user", GID in the newly created user
24#    is set to 0.
25# 5) If we run with "--mount", mount and unmount events do not propagate to
26#    its parent mount namespace.
27# 6) If we run with "--mount --propagation shared", mount and unmount events
28#    propagate to its parent mount namespace.
29# 7) If we run with "--user --map-root-user --mount", mount and unmount events
30#    do not propagate to its parent mount namespace.
31# 8) Even if we run with "--user --map-root-user --mount --propagation shared",
32#    mount and unmount events do not propagate to its parent mount namespace
33#    because the shared mount is reduced to a slave mount.
34#
35#    Please see the following URL for detailed information:
36#    http://man7.org/linux/man-pages/man7/user_namespaces.7.html
37#    http://man7.org/linux/man-pages/man7/mount_namespaces.7.html
38#
39
40TST_CNT=8
41TST_SETUP=setup
42TST_CLEANUP=cleanup
43TST_TESTFUNC=do_test
44TST_NEEDS_ROOT=1
45TST_NEEDS_TMPDIR=1
46TST_NEEDS_CMDS="unshare id mount umount"
47. tst_test.sh
48
49max_userns_path="/proc/sys/user/max_user_namespaces"
50max_mntns_path="/proc/sys/user/max_mnt_namespaces"
51default_max_userns=-1
52default_max_mntns=-1
53
54setup()
55{
56	# On some distributions(e.g RHEL7.4), the default value of
57	# max_user_namespaces or max_mnt_namespaces is set to 0.
58	# We need to change the default value to run unshare command.
59	if [ -f "${max_userns_path}" ]; then
60		default_max_userns=$(cat "${max_userns_path}")
61		echo 1024 > "${max_userns_path}"
62	fi
63
64	if [ -f "${max_mntns_path}" ]; then
65		default_max_mntns=$(cat "${max_mntns_path}")
66		echo 1024 > "${max_mntns_path}"
67	fi
68
69	mkdir -p dir_A dir_B
70	touch dir_A/A dir_B/B
71}
72
73cleanup()
74{
75	# Restore the default value to 0.
76	[ ${default_max_userns} -ne -1 ] && \
77		echo ${default_max_userns} > "${max_userns_path}"
78	[ ${default_max_mntns} -ne -1 ] && \
79		echo ${default_max_mntns} > "${max_mntns_path}"
80}
81
82check_id()
83{
84	local act_id="$1"
85	local exp_id="$2"
86	local cmd="$3"
87
88	if [ ${act_id} -ne ${exp_id} ]; then
89		tst_res TFAIL "$cmd got wrong uid/gid"
90	else
91		tst_res TPASS "$cmd got correct uid/gid"
92	fi
93}
94
95check_mount()
96{
97	local tst_dir="$1"
98	local exp_stat="$2"
99	local cmd="$3"
100
101	case ${exp_stat} in
102	unmounted)
103		if ls "${tst_dir}" | grep -qw 'A'; then
104			tst_res TFAIL "$cmd got bind info"
105			umount ${tst_dir}
106			return
107		fi
108		;;
109	mounted)
110		if ! ls "${tst_dir}" | grep -qw 'A'; then
111			tst_res TFAIL "$cmd did not get bind info"
112			return
113		fi
114		umount ${tst_dir}
115		;;
116	esac
117
118	tst_res TPASS "$cmd got bind info as expected"
119}
120
121unshare_test()
122{
123	local unshare_opts="$1"
124	local verify_cmd="$2"
125	local exp_result="$3"
126
127	local unshare_cmd="unshare ${unshare_opts} ${verify_cmd}"
128
129	eval ${unshare_cmd} > temp 2>&1
130	if [ $? -ne 0 ]; then
131		# unrecognized option or invalid option is returned if the
132		# option is not supported by unshare command(e.g. RHEL6).
133		# Invalid argument or Operation not permitted is returned
134		# if the feature is not supported by kernel(e.g. RHEL7).
135		grep -q -E "unrecognized option|invalid option|Invalid argument|Operation not permitted" temp
136		if [ $? -eq 0 ]; then
137			tst_res TCONF "${unshare_cmd} not supported."
138		else
139			tst_res TFAIL "${unshare_cmd} failed."
140		fi
141		return
142	fi
143
144	case ${verify_cmd} in
145	id*)
146		check_id "$(cat temp)" "${exp_result}" "${unshare_cmd}"
147		;;
148	mount*)
149		check_mount "dir_B" "${exp_result}" "${unshare_cmd}"
150		;;
151	esac
152}
153
154do_test()
155{
156	case $1 in
157	1) unshare_test "--user" "id -u" "65534";;
158	2) unshare_test "--user" "id -g" "65534";;
159	3) unshare_test "--user --map-root-user" "id -u" "0";;
160	4) unshare_test "--user --map-root-user" "id -g" "0";;
161	5) unshare_test "--mount" "mount --bind dir_A dir_B" "unmounted";;
162	6) unshare_test "--mount --propagation shared" \
163			"mount --bind dir_A dir_B" "mounted";;
164	7) unshare_test "--user --map-root-user --mount" \
165			"mount --bind dir_A dir_B" "unmounted";;
166	8) unshare_test "--user --map-root-user --mount --propagation shared" \
167			"mount --bind dir_A dir_B" "unmounted";;
168	esac
169}
170
171tst_run
172