From cc351f419dd7455991efd1bf33c3a34b90e34130 Mon Sep 17 00:00:00 2001 From: Filippo Squillace Date: Sun, 28 Oct 2018 17:34:45 +1100 Subject: [PATCH] Add check for disabled unprivileged user namespace --- README.md | 22 ++++++++++++++++++---- lib/core/common.sh | 1 + lib/core/namespace.sh | 16 +++++++++++++++- tests/unit-tests/test-namespace.sh | 21 +++++++++++++++++++++ 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 713d194..f2c45f2 100644 --- a/README.md +++ b/README.md @@ -425,17 +425,31 @@ Troubleshooting > since JuNest will try to preserve the JuNest environment by assigning ownership > of the files to the real user. -## Not enabled User namespace or kernel too old ## +## Unprivileged user namespace disable at kernel compile time or kernel too old ## -> **Q**: Why do I get warning when I run JuNest via Linux namespaces? +> **Q**: Why do I get this warning when I run JuNest via Linux namespaces? $> junest -u - User namespace is not enabled or Kernel too old (<3.8). Proceeding anyway... + Unprivileged user namespace is disabled at kernel compile time or kernel too old (<3.8). Proceeding anyway... + +> **A**: This means that JuNest detected that the host OS either +> does not have a newer kernel version or the unprivileged user namespace +> is not enabled at kernel compile time. +> JuNest does not stop the execution of the program but it attempts to run it +> anyway. Try to use Proot as backend program in case is not possible to invoke namespaces. + +## Unprivileged user namespace disabled + +> **Q**: Why do I get this warning when I run JuNest via Linux namespaces? + + $> junest -u + Unprivileged user namespace disabled. Root permissions are required to enable it: sudo sysctl kernel.unprivileged_userns_clone=1 > **A**: This means that JuNest detected that the host OS either > does not have a newer Linux version or the user namespace is not enabled. > JuNest does not stop the execution of the program but it attempts to run it -> anyway. Try to use Proot as backend program in case is not possible to invoke namespaces. +> anyway. If you have root permissions try to enable it, otherwise try to use +> Proot as backend program. More documentation ================== diff --git a/lib/core/common.sh b/lib/core/common.sh index 8b15d57..a43df83 100644 --- a/lib/core/common.sh +++ b/lib/core/common.sh @@ -18,6 +18,7 @@ ROOT_ACCESS_ERROR=105 NESTED_ENVIRONMENT=106 VARIABLE_NOT_SET=107 NO_CONFIG_FOUND=108 +UNPRIVILEGED_USERNS_DISABLED=109 JUNEST_HOME=${JUNEST_HOME:-~/.${CMD}} JUNEST_BASE=${JUNEST_BASE:-${JUNEST_HOME}/opt/junest} diff --git a/lib/core/namespace.sh b/lib/core/namespace.sh index 6acd21d..686fabe 100644 --- a/lib/core/namespace.sh +++ b/lib/core/namespace.sh @@ -13,6 +13,7 @@ CONFIG_PROC_FILE="/proc/config.gz" CONFIG_BOOT_FILE="/boot/config-$($UNAME -r)" +PROC_USERNS_CLONE_FILE="/proc/sys/kernel/unprivileged_userns_clone" function _is_user_namespace_enabled() { local config_file="" @@ -30,6 +31,18 @@ function _is_user_namespace_enabled() { then return $NO_CONFIG_FOUND fi + + if [[ ! -e $PROC_USERNS_CLONE_FILE ]] + then + return 0 + fi + + if ! zgrep_cmd -q "1" $PROC_USERNS_CLONE_FILE + then + return $UNPRIVILEGED_USERNS_DISABLED + fi + + return 0 } function _check_user_namespace() { @@ -37,7 +50,8 @@ function _check_user_namespace() { _is_user_namespace_enabled case $? in $NOT_EXISTING_FILE) warn "Could not understand if user namespace is enabled. No config.gz file found. Proceeding anyway..." ;; - $NO_CONFIG_FOUND) warn "User namespace is not enabled or Kernel too old (<3.8). Proceeding anyway..." ;; + $NO_CONFIG_FOUND) warn "Unprivileged user namespace is disabled at kernel compile time or kernel too old (<3.8). Proceeding anyway..." ;; + $UNPRIVILEGED_USERNS_DISABLED) warn "Unprivileged user namespace disabled. Root permissions are required to enable it: sudo sysctl kernel.unprivileged_userns_clone=1" ;; esac set -e } diff --git a/tests/unit-tests/test-namespace.sh b/tests/unit-tests/test-namespace.sh index c4e0f8d..005ab0d 100755 --- a/tests/unit-tests/test-namespace.sh +++ b/tests/unit-tests/test-namespace.sh @@ -75,6 +75,27 @@ function test_is_user_namespace_enabled_with_config(){ gzip config CONFIG_PROC_FILE="config.gz" CONFIG_BOOT_FILE="blah" + PROC_USERNS_CLONE_FILE="not-existing-file" + assertCommandSuccess _is_user_namespace_enabled +} + +function test_is_user_namespace_enabled_with_userns_clone_file_disabled(){ + echo "CONFIG_USER_NS=y" > config + gzip config + CONFIG_PROC_FILE="config.gz" + CONFIG_BOOT_FILE="blah" + PROC_USERNS_CLONE_FILE="unprivileged_userns_clone" + echo "0" > $PROC_USERNS_CLONE_FILE + assertCommandFailOnStatus $UNPRIVILEGED_USERNS_DISABLED _is_user_namespace_enabled +} + +function test_is_user_namespace_enabled_with_userns_clone_file_enabled(){ + echo "CONFIG_USER_NS=y" > config + gzip config + CONFIG_PROC_FILE="config.gz" + CONFIG_BOOT_FILE="blah" + PROC_USERNS_CLONE_FILE="unprivileged_userns_clone" + echo "1" > $PROC_USERNS_CLONE_FILE assertCommandSuccess _is_user_namespace_enabled }