File: //proc/thread-self/root/proc/thread-self/root/bin/cagefs_enter
#!/usr/bin/bash
get_binary() {
temp=`whereis -b $1`
array=( $temp )
length=${#array[@]}
if [ "$length" -eq 1 ]; then
echo $1
fi
length=$(($length - 1))
for i in `seq 1 $length`; do
if [ -x "${array[$i]}" ]; then
echo ${array[$i]}
fi
done
}
ID=$(get_binary id)
WHOAMI=$(get_binary whoami)
TAIL=$(get_binary tail)
PWD=$(get_binary pwd)
SSH=$(get_binary ssh)
CAT=$(get_binary cat)
GREP=$(get_binary grep)
is_cagefs_enabled() {
# return 0 when cagefs is enabled for user
/bin/cagefs_enter.proxied ls -ld /var/.cagefs > /dev/null 2>&1
return $?
}
is_proxy_enabled() {
# return 0 when execution via proxy is enabled
if $GREP -P '^cagefs_enter_proxied\s*=\s*0' /etc/sysconfig/cloudlinux > /dev/null 2>&1; then
return 1
fi
return 0
}
##CageFS proxyexec wrapper - ver 16
# POSIX single-quote escaping for values embedded in the ssh remote command.
# Unlike `printf %q`, single-quoted output re-parses correctly under any POSIX
# shell (the origin login shell need not be bash) and is lossless for arbitrary
# bytes. Each embedded ' becomes the '\'' sequence. (parity with
# proxyexec/cagefs.proxy.program, CLOS-4596)
sq() {
local s=${1//\'/\'\\\'\'}
printf "'%s'" "$s"
}
USR=`$WHOAMI`
if [ "$USR" == "root" ]; then
echo "This program can not be run as root"
exit 1
fi
is_proxy_enabled
proxy_enabled=$?
if [ "$proxy_enabled" -ne 0 ]; then
# when proxy is disabled - call original cagefs_enter binary
/bin/cagefs_enter.proxied "$@"
exit $?
fi
PREFIX=`$ID -u|$TAIL -c 3`
USER_TOKEN_PATH="/var/cagefs/$PREFIX/$USR/.cagefs/.cagefs.token"
WEBSITE_ISOLATION_FLAG="/opt/cloudlinux/flags/enabled-flags.d/website-isolation.flag"
# WEBSITE_TOKEN_PATH override — DO NOT REMOVE.
#
# This is the IPC contract that lets `cagefs_enter_site DOMAIN cmd` enter the
# per-website jail (where proxyexec applies the :secure-flag policy and the
# per-domain bind-mount over /var/.cagefs/ exposes .cagefs.website). The Python
# wrapper at clcagefslib.webisolation.libenter.enter_site() invokes this script
# with WEBSITE_TOKEN_PATH set to the per-website token path; without this block
# we silently fall back to the user-level jail and website isolation becomes a
# no-op (broke `cagefs.python_tests.test_isolated_domains_enter` and
# `test_proxyexec_secure` when removed in CLOS-4125 / 0.7.13-2).
#
# Why it's safe despite looking like a "user-controlled path read":
# - This script runs as the calling user, never setuid; reading $TOKEN gives
# no privilege the user does not already have.
# - Token files are mode 0400 owned by the rightful user; another user cannot
# read them, so the override cannot be used to enter another user's jail.
# - The token value is sent to proxyexec which validates it server-side
# against its registry. An invented or wrong token is rejected.
# - The override is gated by WEBSITE_ISOLATION_FLAG: it activates only on
# hosts where the website-isolation feature is enabled.
# - The shell-injection risk that the AI scanner originally flagged was the
# unquoted `$CAT $USER_TOKEN_PATH` below (now `$("$CAT" "$USER_TOKEN_PATH")`).
# Quoting fixed that independently; removing the override gave no further
# security gain but broke the feature.
#
# If you ever need to close this env-var IPC channel, you must replace it with
# an alternative contract (e.g. an explicit CLI flag) AND simultaneously update
# clcagefslib.webisolation.libenter.enter_site to use it.
if [ -f "$WEBSITE_ISOLATION_FLAG" ] && [ -n "$WEBSITE_TOKEN_PATH" ]; then
USER_TOKEN_PATH="$WEBSITE_TOKEN_PATH"
else
if [ ! -f "$USER_TOKEN_PATH" ]; then
# try to create token
is_cagefs_enabled
cagefs_enabled=$?
fi
fi
if [ ! -f "$USER_TOKEN_PATH" ]; then
# when token does not exist - call original cagefs_enter binary
/bin/cagefs_enter.proxied "$@"
exit $?
fi
TOKEN=$("$CAT" "$USER_TOKEN_PATH")
CWD=`$PWD`
# Reject a non-alphanumeric token before it is forwarded. Tokens are generated
# as fixed-length alphanumerics, so anything else indicates tampering. POSIX
# `case` (not [[ =~ ]]) so this also works under dash.
case "$TOKEN" in
"" | *[!A-Za-z0-9]*)
echo "cagefs_enter: refusing to forward malformed token from $USER_TOKEN_PATH" >&2
exit 1
;;
esac
if [ -e /var/.cagefs/origin ]; then
ORIGIN=`$CAT /var/.cagefs/origin`
# Single-quote every caller-controlled value (CWD and each "$@") with sq()
# before composing the ssh remote command, which the origin login shell
# re-parses; sq() output survives one re-parse unchanged. The validated
# alphanumeric $TOKEN needs no quoting. Rationale: see CLOS-4583 / git log.
Q_ARGS=
for _arg in "$@"; do
Q_ARGS="$Q_ARGS $(sq "$_arg")"
done
$SSH -F /etc/ssh/cagefs-rexec_config "$USR@$ORIGIN" \
"CAGEFS_TOKEN=$TOKEN /usr/sbin/proxyexec -c cagefs.sock $(sq "$USR") $(sq "$CWD") CAGEFS_ENTER $$$Q_ARGS"
else
CAGEFS_TOKEN="$TOKEN" /usr/sbin/proxyexec -c cagefs.sock "$USR" "$CWD" CAGEFS_ENTER $$ "$@"
fi
exit $?