Skip to content

Commit 32d6e48

Browse files
CopilotlpcoxCopilot
authored
refactor(entrypoint): deduplicate signal-handler + token-cleanup into shared function (#2565)
* Initial plan * refactor: extract run_agent_with_token_protection helper function * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Landon Cox <landon.cox@microsoft.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent b81351c commit 32d6e48

1 file changed

Lines changed: 53 additions & 66 deletions

File tree

containers/agent/entrypoint.sh

Lines changed: 53 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,55 @@ unset_sensitive_tokens() {
397397
done
398398
}
399399

400+
# Run a command with signal handling, one-shot token protection, and clean exit.
401+
# Usage: run_agent_with_token_protection <command> [args...]
402+
# The command is launched in the background so that sensitive tokens can be unset
403+
# from the parent shell's environment once the agent has had time to cache them.
404+
run_agent_with_token_protection() {
405+
# Setup signal handler to forward signals to agent process and perform cleanup
406+
cleanup_and_exit() {
407+
SIGNAL="$1"
408+
EXIT_CODE=143
409+
if [ "$SIGNAL" = "INT" ]; then
410+
EXIT_CODE=130 # Standard exit code for SIGINT
411+
fi
412+
413+
trap - TERM INT
414+
415+
if [ -n "$AGENT_PID" ]; then
416+
kill "-$SIGNAL" "$AGENT_PID" 2>/dev/null || true
417+
wait "$AGENT_PID" 2>/dev/null || true
418+
fi
419+
420+
exit "$EXIT_CODE"
421+
}
422+
trap 'cleanup_and_exit TERM' TERM
423+
trap 'cleanup_and_exit INT' INT
424+
425+
# SECURITY: Run agent command in background, then unset tokens from parent shell
426+
# This prevents tokens from being accessible via /proc/1/environ after agent starts
427+
# The one-shot-token library caches tokens in the agent process, so agent can still read them
428+
"$@" &
429+
AGENT_PID=$!
430+
431+
# Wait for agent to initialize and cache tokens (up to 1 second)
432+
# The one-shot-token LD_PRELOAD library caches tokens in ~100ms during process init.
433+
# Poll every 100ms so fast commands (e.g. 'echo ok') don't pay the full wait.
434+
for _i in 1 2 3 4 5 6 7 8 9 10; do
435+
kill -0 "$AGENT_PID" 2>/dev/null || break
436+
sleep 0.1
437+
done
438+
439+
# Unset all sensitive tokens from parent shell environment
440+
unset_sensitive_tokens
441+
442+
# Wait for agent command to complete and capture its exit code
443+
wait $AGENT_PID
444+
EXIT_CODE=$?
445+
trap - TERM INT
446+
exit $EXIT_CODE
447+
}
448+
400449
echo "[entrypoint] Switching to awfuser (UID: $(id -u awfuser), GID: $(id -g awfuser))"
401450
echo "[entrypoint] Executing command: $@"
402451
echo ""
@@ -848,43 +897,12 @@ AWFEOF
848897
LD_PRELOAD_CMD="export LD_PRELOAD=${ONE_SHOT_TOKEN_LIB};"
849898
fi
850899

851-
# Setup signal handler to forward signals to agent process and perform cleanup
852-
cleanup_and_exit() {
853-
if [ -n "$AGENT_PID" ]; then
854-
kill -TERM "$AGENT_PID" 2>/dev/null || true
855-
wait "$AGENT_PID" 2>/dev/null || true
856-
fi
857-
exit 143 # Standard exit code for SIGTERM
858-
}
859-
trap cleanup_and_exit TERM INT
860-
861-
# SECURITY: Run agent command in background, then unset tokens from parent shell
862-
# This prevents tokens from being accessible via /proc/1/environ after agent starts
863-
# The one-shot-token library caches tokens in the agent process, so agent can still read them
864-
chroot /host /bin/bash -c "
900+
run_agent_with_token_protection chroot /host /bin/bash -c "
865901
cd '${CHROOT_WORKDIR}' 2>/dev/null || cd /
866902
trap '${CLEANUP_CMD}' EXIT
867903
${LD_PRELOAD_CMD}
868904
exec capsh --drop=${CAPS_TO_DROP} --user=${HOST_USER} -- -c 'exec ${SCRIPT_FILE}'
869-
" &
870-
AGENT_PID=$!
871-
872-
# Wait for agent to initialize and cache tokens (up to 1 second)
873-
# The one-shot-token LD_PRELOAD library caches tokens in ~100ms during process init.
874-
# Poll every 100ms so fast commands (e.g. 'echo ok') don't pay the full wait.
875-
for _i in 1 2 3 4 5 6 7 8 9 10; do
876-
kill -0 "$AGENT_PID" 2>/dev/null || break
877-
sleep 0.1
878-
done
879-
880-
# Unset all sensitive tokens from parent shell environment
881-
unset_sensitive_tokens
882-
883-
# Wait for agent command to complete and capture its exit code
884-
wait $AGENT_PID
885-
EXIT_CODE=$?
886-
trap - TERM INT
887-
exit $EXIT_CODE
905+
"
888906
else
889907
# Original behavior - run in container filesystem
890908
# Drop capabilities and privileges, then execute the user command
@@ -915,41 +933,10 @@ else
915933
# unset from the environment so /proc/self/environ is cleared
916934
export LD_PRELOAD=/usr/local/lib/one-shot-token.so
917935

918-
# Setup signal handler to forward signals to agent process and perform cleanup
919-
cleanup_and_exit() {
920-
if [ -n "$AGENT_PID" ]; then
921-
kill -TERM "$AGENT_PID" 2>/dev/null || true
922-
wait "$AGENT_PID" 2>/dev/null || true
923-
fi
924-
exit 143 # Standard exit code for SIGTERM
925-
}
926-
trap cleanup_and_exit TERM INT
927-
928-
# SECURITY: Run agent command in background, then unset tokens from parent shell
929-
# This prevents tokens from being accessible via /proc/1/environ after agent starts
930-
# The one-shot-token library caches tokens in the agent process, so agent can still read them
931936
if [ -n "$CAPS_TO_DROP" ]; then
932-
capsh --drop=$CAPS_TO_DROP -- -c "exec gosu awfuser $(printf '%q ' "$@")" &
937+
run_agent_with_token_protection capsh --drop=$CAPS_TO_DROP -- -c "exec gosu awfuser $(printf '%q ' "$@")"
933938
else
934939
# No capabilities to drop - just switch to unprivileged user
935-
gosu awfuser "$@" &
940+
run_agent_with_token_protection gosu awfuser "$@"
936941
fi
937-
AGENT_PID=$!
938-
939-
# Wait for agent to initialize and cache tokens (up to 1 second)
940-
# The one-shot-token LD_PRELOAD library caches tokens in ~100ms during process init.
941-
# Poll every 100ms so fast commands (e.g. 'echo ok') don't pay the full wait.
942-
for _i in 1 2 3 4 5 6 7 8 9 10; do
943-
kill -0 "$AGENT_PID" 2>/dev/null || break
944-
sleep 0.1
945-
done
946-
947-
# Unset all sensitive tokens from parent shell environment
948-
unset_sensitive_tokens
949-
950-
# Wait for agent command to complete and capture its exit code
951-
wait $AGENT_PID
952-
EXIT_CODE=$?
953-
trap - TERM INT
954-
exit $EXIT_CODE
955942
fi

0 commit comments

Comments
 (0)