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