xref: /aosp_15_r20/external/ltp/testcases/commands/unshare/unshare01.sh (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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 <[email protected]>
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
37max_userns_path="/proc/sys/user/max_user_namespaces"
38max_mntns_path="/proc/sys/user/max_mnt_namespaces"
39default_max_userns=-1
40default_max_mntns=-1
41
42setup()
43{
44	# On some distributions(e.g RHEL7.4), the default value of
45	# max_user_namespaces or max_mnt_namespaces is set to 0.
46	# We need to change the default value to run unshare command.
47	if [ -f "${max_userns_path}" ]; then
48		default_max_userns=$(cat "${max_userns_path}")
49		echo 1024 > "${max_userns_path}"
50	fi
51
52	if [ -f "${max_mntns_path}" ]; then
53		default_max_mntns=$(cat "${max_mntns_path}")
54		echo 1024 > "${max_mntns_path}"
55	fi
56
57	mkdir -p dir_A dir_B
58	touch dir_A/A dir_B/B
59}
60
61cleanup()
62{
63	# Restore the default value to 0.
64	[ ${default_max_userns} -ne -1 ] && \
65		echo ${default_max_userns} > "${max_userns_path}"
66	[ ${default_max_mntns} -ne -1 ] && \
67		echo ${default_max_mntns} > "${max_mntns_path}"
68}
69
70check_id()
71{
72	local act_id="$1"
73	local exp_id="$2"
74	local cmd="$3"
75
76	if [ ${act_id} -ne ${exp_id} ]; then
77		tst_res TFAIL "$cmd got wrong uid/gid"
78	else
79		tst_res TPASS "$cmd got correct uid/gid"
80	fi
81}
82
83check_mount()
84{
85	local tst_dir="$1"
86	local exp_stat="$2"
87	local cmd="$3"
88
89	case ${exp_stat} in
90	unmounted)
91		if ls "${tst_dir}" | grep -qw 'A'; then
92			tst_res TFAIL "$cmd got bind info"
93			umount ${tst_dir}
94			return
95		fi
96		;;
97	mounted)
98		if ! ls "${tst_dir}" | grep -qw 'A'; then
99			tst_res TFAIL "$cmd did not get bind info"
100			return
101		fi
102		umount ${tst_dir}
103		;;
104	esac
105
106	tst_res TPASS "$cmd got bind info as expected"
107}
108
109unshare_test()
110{
111	local unshare_opts="$1"
112	local verify_cmd="$2"
113	local exp_result="$3"
114
115	local unshare_cmd="unshare ${unshare_opts} ${verify_cmd}"
116
117	eval ${unshare_cmd} > temp 2>&1
118	if [ $? -ne 0 ]; then
119		# unrecognized option or invalid option is returned if the
120		# option is not supported by unshare command(e.g. RHEL6).
121		# Invalid argument or Operation not permitted is returned
122		# if the feature is not supported by kernel(e.g. RHEL7).
123		grep -q -E "unrecognized option|invalid option|Invalid argument|Operation not permitted" temp
124		if [ $? -eq 0 ]; then
125			tst_res TCONF "${unshare_cmd} not supported."
126		else
127			tst_res TFAIL "${unshare_cmd} failed."
128		fi
129		return
130	fi
131
132	case ${verify_cmd} in
133	id*)
134		check_id "$(cat temp)" "${exp_result}" "${unshare_cmd}"
135		;;
136	mount*)
137		check_mount "dir_B" "${exp_result}" "${unshare_cmd}"
138		;;
139	esac
140}
141
142do_test()
143{
144	case $1 in
145	1) unshare_test "--user" "id -u" "65534";;
146	2) unshare_test "--user" "id -g" "65534";;
147	3) unshare_test "--user --map-root-user" "id -u" "0";;
148	4) unshare_test "--user --map-root-user" "id -g" "0";;
149	5) unshare_test "--mount" "mount --bind dir_A dir_B" "unmounted";;
150	6) unshare_test "--mount --propagation shared" \
151			"mount --bind dir_A dir_B" "mounted";;
152	7) unshare_test "--user --map-root-user --mount" \
153			"mount --bind dir_A dir_B" "unmounted";;
154	8) unshare_test "--user --map-root-user --mount --propagation shared" \
155			"mount --bind dir_A dir_B" "unmounted";;
156	esac
157}
158
159. tst_test.sh
160tst_run
161