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