unshare01.sh 4.4 KB

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