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