Fix capabilities
This commit is contained in:
@@ -211,6 +211,33 @@ teardown_stub_env() {
|
||||
rm -f "${STUB_LOG:-}"
|
||||
}
|
||||
|
||||
extract_embedded_helper() {
|
||||
local helper=$1
|
||||
local output=$2
|
||||
if ! awk -v helper="$helper" '
|
||||
$0 ~ "^[[:space:]]*" helper "\\)$" { state=1; next }
|
||||
state == 1 && /cat <<'\''EOF'\''$/ { state=2; next }
|
||||
state == 2 && /^EOF$/ { exit }
|
||||
state == 2 { print }
|
||||
' "$SLOPTRAP_BIN" >"$output"; then
|
||||
return 1
|
||||
fi
|
||||
chmod +x "$output"
|
||||
}
|
||||
|
||||
wait_for_path() {
|
||||
local path=$1
|
||||
local attempts=${2:-100}
|
||||
while (( attempts > 0 )); do
|
||||
if [[ -e $path ]]; then
|
||||
return 0
|
||||
fi
|
||||
sleep 0.1
|
||||
((attempts-=1))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
record_failure() {
|
||||
failures+=("$1")
|
||||
}
|
||||
@@ -302,6 +329,22 @@ run_secret_mask() {
|
||||
teardown_stub_env
|
||||
}
|
||||
|
||||
run_git_ignore_mask() {
|
||||
local scenario_dir="$ROOT_DIR"
|
||||
printf '==> git_ignore_mask\n'
|
||||
setup_stub_env
|
||||
if ! PATH="$STUB_BIN:$PATH" HOME="$STUB_HOME" FAKE_PODMAN_LOG="$STUB_LOG" FAKE_PODMAN_INSPECT_FAIL=1 \
|
||||
"$SLOPTRAP_BIN" --trust-capabilities "$scenario_dir" </dev/null >/dev/null 2>&1; then
|
||||
record_failure "git_ignore_mask: sloptrap exited non-zero"
|
||||
teardown_stub_env
|
||||
return
|
||||
fi
|
||||
if ! grep -q -- "--mount type=tmpfs,target=/workspace/.git" "$STUB_LOG"; then
|
||||
record_failure "git_ignore_mask: .git was not masked with tmpfs"
|
||||
fi
|
||||
teardown_stub_env
|
||||
}
|
||||
|
||||
run_resume_target() {
|
||||
local scenario_dir="$TEST_ROOT/resume_target"
|
||||
printf '==> resume_target\n'
|
||||
@@ -335,10 +378,9 @@ run_runtime_context_prompt() {
|
||||
if [[ -z $run_line || $run_line != *"You are running inside sloptrap"* ]]; then
|
||||
record_failure "runtime_context_prompt: startup prompt missing from fresh run"
|
||||
fi
|
||||
if ! grep -q -- "manifest_present=true" "$STUB_LOG" \
|
||||
|| ! grep -q -- "manifest_capabilities=apt-install nested-podman packet-capture" "$STUB_LOG" \
|
||||
|| ! grep -q -- "trusted_capabilities=apt-install nested-podman packet-capture" "$STUB_LOG" \
|
||||
|| ! grep -q -- "enabled_capabilities=apt-install nested-podman packet-capture" "$STUB_LOG"; then
|
||||
if ! grep -q -- "name=capability-repo" "$STUB_LOG" \
|
||||
|| ! grep -q -- "enabled_capabilities=apt-install nested-podman packet-capture" "$STUB_LOG" \
|
||||
|| ! grep -q -- "network_mode=host" "$STUB_LOG"; then
|
||||
record_failure "runtime_context_prompt: runtime summary missing manifest or capability state"
|
||||
fi
|
||||
if [[ -n $login_line && $login_line == *"You are running inside sloptrap"* ]]; then
|
||||
@@ -690,7 +732,7 @@ run_capability_profiles() {
|
||||
teardown_stub_env
|
||||
return
|
||||
fi
|
||||
if ! grep -q -- "CAPABILITY_PACKAGES=tcpdump podman fuse-overlayfs slirp4netns" "$STUB_LOG"; then
|
||||
if ! grep -q -- "CAPABILITY_PACKAGES=tcpdump podman uidmap fuse-overlayfs slirp4netns" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: build arg for capability packages missing"
|
||||
fi
|
||||
if ! grep -q -- "--cap-add NET_RAW" "$STUB_LOG"; then
|
||||
@@ -702,21 +744,279 @@ run_capability_profiles() {
|
||||
if ! grep -q -- "--device /dev/fuse" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: /dev/fuse device missing"
|
||||
fi
|
||||
if ! grep -q -- "--cap-add SETUID" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: SETUID capability missing"
|
||||
fi
|
||||
if ! grep -q -- "--cap-add SETGID" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: SETGID capability missing"
|
||||
fi
|
||||
if ! grep -q -- "--cap-add CHOWN" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: CHOWN capability missing"
|
||||
fi
|
||||
if ! grep -q -- "--cap-add DAC_OVERRIDE" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: DAC_OVERRIDE capability missing"
|
||||
fi
|
||||
if ! grep -q -- "--cap-add FOWNER" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: FOWNER capability missing"
|
||||
fi
|
||||
if grep -q -- "--read-only" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: apt profile should disable read-only rootfs"
|
||||
fi
|
||||
if grep -q -- "--user " "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: capability-enabled run should not force --user"
|
||||
fi
|
||||
if ! grep -q -- "--userns=keep-id:uid=$(id -u),gid=$(id -g)" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: podman keep-id user namespace missing"
|
||||
fi
|
||||
if ! grep -q -- "SLOPTRAP_ACTIVE_CAPABILITIES=apt-install nested-podman packet-capture" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: active capability environment missing"
|
||||
fi
|
||||
if ! grep -q -- "SLOPTRAP_HOST_UID=$(id -u)" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: host uid environment missing"
|
||||
fi
|
||||
if ! grep -q -- "SLOPTRAP_HOST_GID=$(id -g)" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: host gid environment missing"
|
||||
fi
|
||||
if ! grep -q -- "SLOPTRAP_INNER_PODMAN_HOST_NETWORK=1" "$STUB_LOG"; then
|
||||
record_failure "capability_profiles: inner podman host-network mirror flag missing"
|
||||
fi
|
||||
local state_root capability_dir
|
||||
state_root="$STUB_HOME/.codex/sloptrap/state"
|
||||
capability_dir=$(find "$state_root" -mindepth 2 -maxdepth 2 -type d -name capabilities | head -n 1 || true)
|
||||
if [[ -z $capability_dir ]]; then
|
||||
record_failure "capability_profiles: project capability state directory missing"
|
||||
else
|
||||
if [[ ! -d $capability_dir/podman-storage ]]; then
|
||||
record_failure "capability_profiles: nested podman storage state missing"
|
||||
fi
|
||||
if [[ ! -d $capability_dir/podman-run ]]; then
|
||||
record_failure "capability_profiles: nested podman runroot state missing"
|
||||
fi
|
||||
if [[ ! -d $capability_dir/podman-runtime ]]; then
|
||||
record_failure "capability_profiles: nested podman runtime state missing"
|
||||
fi
|
||||
fi
|
||||
teardown_stub_env
|
||||
}
|
||||
|
||||
run_embedded_capability_helpers() {
|
||||
printf '==> embedded_capability_helpers\n'
|
||||
local temp_root helper_bin helper_dir workspace_dir capture_dir tool_log helper_pid
|
||||
local inner_podman_root inner_podman_runroot inner_runtime_dir
|
||||
temp_root=$(mktemp -d)
|
||||
helper_bin="$temp_root/bin"
|
||||
helper_dir="$temp_root/helper"
|
||||
workspace_dir="$temp_root/workspace"
|
||||
capture_dir="$temp_root/captures"
|
||||
tool_log="$temp_root/tool.log"
|
||||
inner_podman_root="$temp_root/podman-storage"
|
||||
inner_podman_runroot="$temp_root/podman-run"
|
||||
inner_runtime_dir="$temp_root/podman-runtime"
|
||||
helper_pid=""
|
||||
mkdir -p "$helper_bin" "$helper_dir/queue" "$workspace_dir/data" "$capture_dir" \
|
||||
"$inner_podman_root" "$inner_podman_runroot" "$inner_runtime_dir"
|
||||
: >"$tool_log"
|
||||
|
||||
if ! extract_embedded_helper "sloptrap-entrypoint" "$helper_bin/sloptrap-entrypoint" \
|
||||
|| ! extract_embedded_helper "sloptrap-helperd" "$helper_bin/sloptrap-helperd" \
|
||||
|| ! extract_embedded_helper "slop-apt" "$helper_bin/slop-apt" \
|
||||
|| ! extract_embedded_helper "slopcap" "$helper_bin/slopcap" \
|
||||
|| ! extract_embedded_helper "sloppodman" "$helper_bin/sloppodman"; then
|
||||
record_failure "embedded_capability_helpers: failed to extract embedded helper scripts"
|
||||
rm -rf "$temp_root"
|
||||
return
|
||||
fi
|
||||
|
||||
cat >"$helper_bin/podman" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf 'podman %s\n' "$*" >>"$TEST_TOOL_LOG"
|
||||
exit 0
|
||||
EOF
|
||||
cat >"$helper_bin/apt-get" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf 'apt-get %s\n' "$*" >>"$TEST_TOOL_LOG"
|
||||
exit 0
|
||||
EOF
|
||||
cat >"$helper_bin/tcpdump" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
printf 'tcpdump %s\n' "$*" >>"$TEST_TOOL_LOG"
|
||||
output=""
|
||||
prev=""
|
||||
for arg in "$@"; do
|
||||
if [[ $prev == "-w" ]]; then
|
||||
output=$arg
|
||||
break
|
||||
fi
|
||||
prev=$arg
|
||||
done
|
||||
if [[ -n $output ]]; then
|
||||
mkdir -p "$(dirname "$output")"
|
||||
: >"$output"
|
||||
fi
|
||||
exit 0
|
||||
EOF
|
||||
cat >"$helper_bin/setpriv" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--reuid|--regid)
|
||||
shift 2
|
||||
;;
|
||||
--clear-groups)
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
exec "$@"
|
||||
EOF
|
||||
chmod +x "$helper_bin/podman" "$helper_bin/apt-get" "$helper_bin/tcpdump" "$helper_bin/setpriv"
|
||||
|
||||
if ! grep -q "chmod 711 \"\\\$helper_dir\"" "$helper_bin/sloptrap-entrypoint" \
|
||||
|| ! grep -q "chown \"\\\$target_uid:\\\$target_gid\" \"\\\$queue_dir\"" "$helper_bin/sloptrap-entrypoint"; then
|
||||
record_failure "embedded_capability_helpers: entrypoint did not expose helper queue to the dropped user"
|
||||
fi
|
||||
|
||||
local autostart_helper_dir
|
||||
autostart_helper_dir="$temp_root/helper-autostart"
|
||||
if ! TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$autostart_helper_dir" \
|
||||
SLOPTRAP_ACTIVE_CAPABILITIES="apt-install packet-capture" \
|
||||
SLOPTRAP_CAPTURE_DIR="$capture_dir" SLOPTRAP_WORKDIR="$workspace_dir" \
|
||||
SLOPTRAP_AUDIT_LOG="$temp_root/autostart-audit.log" \
|
||||
SLOPTRAP_HOST_UID="$(id -u)" SLOPTRAP_HOST_GID="$(id -g)" \
|
||||
"$helper_bin/slop-apt" install jq >/dev/null 2>&1; then
|
||||
record_failure "embedded_capability_helpers: slop-apt did not self-bootstrap the helper daemon"
|
||||
fi
|
||||
if [[ ! -r $autostart_helper_dir/helperd.pid ]]; then
|
||||
record_failure "embedded_capability_helpers: helper self-bootstrap did not create a pid file"
|
||||
else
|
||||
kill "$(cat "$autostart_helper_dir/helperd.pid")" >/dev/null 2>&1 || true
|
||||
wait "$(cat "$autostart_helper_dir/helperd.pid")" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
local missing_cap_status=0
|
||||
if TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_ACTIVE_CAPABILITIES="" \
|
||||
SLOPTRAP_WORKDIR="$workspace_dir" \
|
||||
SLOPTRAP_INNER_PODMAN_ROOT="$inner_podman_root" \
|
||||
SLOPTRAP_INNER_PODMAN_RUNROOT="$inner_podman_runroot" \
|
||||
XDG_RUNTIME_DIR="$inner_runtime_dir" \
|
||||
"$helper_bin/sloppodman" ps >/dev/null 2>&1; then
|
||||
record_failure "embedded_capability_helpers: sloppodman should reject runs without nested-podman"
|
||||
else
|
||||
missing_cap_status=$?
|
||||
fi
|
||||
if [[ $missing_cap_status -ne 126 ]]; then
|
||||
record_failure "embedded_capability_helpers: sloppodman returned the wrong status when capability was absent"
|
||||
fi
|
||||
|
||||
if TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_ACTIVE_CAPABILITIES="nested-podman" \
|
||||
SLOPTRAP_WORKDIR="$workspace_dir" \
|
||||
SLOPTRAP_INNER_PODMAN_ROOT="$inner_podman_root" \
|
||||
SLOPTRAP_INNER_PODMAN_RUNROOT="$inner_podman_runroot" \
|
||||
XDG_RUNTIME_DIR="$inner_runtime_dir" \
|
||||
"$helper_bin/sloppodman" run --privileged example/image >/dev/null 2>&1; then
|
||||
record_failure "embedded_capability_helpers: sloppodman allowed --privileged"
|
||||
fi
|
||||
|
||||
if TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_ACTIVE_CAPABILITIES="nested-podman" \
|
||||
SLOPTRAP_WORKDIR="$workspace_dir" \
|
||||
SLOPTRAP_INNER_PODMAN_ROOT="$inner_podman_root" \
|
||||
SLOPTRAP_INNER_PODMAN_RUNROOT="$inner_podman_runroot" \
|
||||
XDG_RUNTIME_DIR="$inner_runtime_dir" \
|
||||
"$helper_bin/sloppodman" run -v /tmp:/host example/image >/dev/null 2>&1; then
|
||||
record_failure "embedded_capability_helpers: sloppodman allowed an out-of-workspace bind mount"
|
||||
fi
|
||||
|
||||
if ! (
|
||||
cd "$workspace_dir" && TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" \
|
||||
SLOPTRAP_ACTIVE_CAPABILITIES="nested-podman" SLOPTRAP_WORKDIR="$workspace_dir" \
|
||||
SLOPTRAP_INNER_PODMAN_ROOT="$inner_podman_root" \
|
||||
SLOPTRAP_INNER_PODMAN_RUNROOT="$inner_podman_runroot" \
|
||||
XDG_RUNTIME_DIR="$inner_runtime_dir" \
|
||||
"$helper_bin/sloppodman" run -v ./data:/data example/image true >/dev/null 2>&1
|
||||
); then
|
||||
record_failure "embedded_capability_helpers: sloppodman rejected a workspace-local bind mount"
|
||||
fi
|
||||
if ! grep -q -- 'podman --root ' "$tool_log" || ! grep -q -- '-v ./data:/data' "$tool_log"; then
|
||||
record_failure "embedded_capability_helpers: sloppodman did not invoke podman with the validated run arguments"
|
||||
fi
|
||||
|
||||
TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$helper_dir" \
|
||||
SLOPTRAP_ACTIVE_CAPABILITIES="apt-install packet-capture" \
|
||||
SLOPTRAP_CAPTURE_DIR="$capture_dir" SLOPTRAP_WORKDIR="$workspace_dir" \
|
||||
SLOPTRAP_AUDIT_LOG="$temp_root/audit.log" "$helper_bin/sloptrap-helperd" >/dev/null 2>&1 &
|
||||
helper_pid=$!
|
||||
|
||||
if ! TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$helper_dir" \
|
||||
"$helper_bin/slop-apt" install jq >/dev/null 2>&1; then
|
||||
record_failure "embedded_capability_helpers: slop-apt failed against the embedded helper daemon"
|
||||
fi
|
||||
if ! grep -q -- 'apt-get install -y --no-install-recommends jq' "$tool_log"; then
|
||||
record_failure "embedded_capability_helpers: slop-apt did not reach apt-get install"
|
||||
fi
|
||||
|
||||
local bad_apt_request
|
||||
bad_apt_request=$(mktemp -d "$helper_dir/queue/request.XXXXXX.req")
|
||||
printf 'apt-install\n' >"$bad_apt_request/op"
|
||||
printf '%s\n' '--allow-unauthenticated' >"$bad_apt_request/packages"
|
||||
if ! wait_for_path "$bad_apt_request/status"; then
|
||||
record_failure "embedded_capability_helpers: helper daemon did not answer the invalid apt request"
|
||||
elif [[ $(<"$bad_apt_request/status") != "2" ]]; then
|
||||
record_failure "embedded_capability_helpers: invalid apt request returned the wrong status"
|
||||
fi
|
||||
if [[ -s "$bad_apt_request/stderr" ]] && ! grep -q -- 'invalid package name' "$bad_apt_request/stderr"; then
|
||||
record_failure "embedded_capability_helpers: invalid apt request did not explain the rejection"
|
||||
fi
|
||||
|
||||
if TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$helper_dir" \
|
||||
SLOPTRAP_CAPTURE_DIR="$capture_dir" SLOPTRAP_WORKDIR="$workspace_dir" \
|
||||
"$helper_bin/slopcap" capture --interface eth0 --output /tmp/escape.pcap >/dev/null 2>&1; then
|
||||
record_failure "embedded_capability_helpers: slopcap accepted an out-of-bounds output path"
|
||||
fi
|
||||
|
||||
if ! TEST_TOOL_LOG="$tool_log" PATH="$helper_bin:$PATH" SLOPTRAP_HELPER_DIR="$helper_dir" \
|
||||
SLOPTRAP_CAPTURE_DIR="$capture_dir" SLOPTRAP_WORKDIR="$workspace_dir" \
|
||||
"$helper_bin/slopcap" capture --interface eth0 --filter 'tcp port 80' \
|
||||
--output "$workspace_dir/capture.pcap" >/dev/null 2>&1; then
|
||||
record_failure "embedded_capability_helpers: slopcap failed for a workspace-local capture file"
|
||||
fi
|
||||
if ! grep -q -- "tcpdump -i eth0 -w $workspace_dir/capture.pcap -- tcp port 80" "$tool_log"; then
|
||||
record_failure "embedded_capability_helpers: slopcap did not invoke tcpdump with the expected guarded arguments"
|
||||
fi
|
||||
|
||||
local bad_capture_request
|
||||
bad_capture_request=$(mktemp -d "$helper_dir/queue/request.XXXXXX.req")
|
||||
printf 'packet-capture\n' >"$bad_capture_request/op"
|
||||
printf 'eth0\n' >"$bad_capture_request/interface"
|
||||
printf '\n' >"$bad_capture_request/filter"
|
||||
printf '/tmp/escape.pcap\n' >"$bad_capture_request/output"
|
||||
printf '0\n' >"$bad_capture_request/stdout_mode"
|
||||
if ! wait_for_path "$bad_capture_request/status"; then
|
||||
record_failure "embedded_capability_helpers: helper daemon did not answer the invalid capture request"
|
||||
elif [[ $(<"$bad_capture_request/status") != "2" ]]; then
|
||||
record_failure "embedded_capability_helpers: invalid capture request returned the wrong status"
|
||||
fi
|
||||
if [[ -s "$bad_capture_request/stderr" ]] && ! grep -q -- 'output path must stay within' "$bad_capture_request/stderr"; then
|
||||
record_failure "embedded_capability_helpers: invalid capture request did not explain the rejection"
|
||||
fi
|
||||
|
||||
if [[ -n $helper_pid ]]; then
|
||||
kill "$helper_pid" >/dev/null 2>&1 || true
|
||||
wait "$helper_pid" >/dev/null 2>&1 || true
|
||||
fi
|
||||
rm -rf "$temp_root"
|
||||
}
|
||||
|
||||
run_make_install_single_file() {
|
||||
local scenario_dir="$TEST_ROOT/resume_target"
|
||||
printf '==> make_install_single_file\n'
|
||||
@@ -768,6 +1068,7 @@ run_symlink_escape
|
||||
run_manifest_injection
|
||||
run_helper_symlink
|
||||
run_secret_mask
|
||||
run_git_ignore_mask
|
||||
run_resume_target
|
||||
run_runtime_context_prompt
|
||||
run_sh_reexec
|
||||
@@ -791,6 +1092,7 @@ run_wizard_existing_defaults
|
||||
run_wizard_build_trigger
|
||||
run_capability_trust_required
|
||||
run_capability_profiles
|
||||
run_embedded_capability_helpers
|
||||
run_make_install_single_file
|
||||
|
||||
if [[ ${#failures[@]} -gt 0 ]]; then
|
||||
|
||||
Reference in New Issue
Block a user