fix: revalidate exiting demo anchors
This commit is contained in:
+30
-17
@@ -104,10 +104,12 @@ demo_has_exact_tail() {
|
||||
demo_command_matches() {
|
||||
local root=$1 pid=$2 kind=$3 expected executable interpreter entry_index
|
||||
local -a arguments=()
|
||||
[[ -r "/proc/$pid/cmdline" && -e "/proc/$pid/exe" ]] || return 1
|
||||
{ mapfile -d '' -t arguments <"/proc/$pid/cmdline"; } 2>/dev/null || return 1
|
||||
((${#arguments[@]} > 0)) || return 1
|
||||
executable=$(readlink -f -- "/proc/$pid/exe" 2>/dev/null) || return 1
|
||||
# Status 2 means /proc became unreadable while identity was being checked.
|
||||
# Status 1 remains a definitive command mismatch.
|
||||
[[ -r "/proc/$pid/cmdline" && -e "/proc/$pid/exe" ]] || return 2
|
||||
{ mapfile -d '' -t arguments <"/proc/$pid/cmdline"; } 2>/dev/null || return 2
|
||||
((${#arguments[@]} > 0)) || return 2
|
||||
executable=$(readlink -f -- "/proc/$pid/exe" 2>/dev/null) || return 2
|
||||
|
||||
if [[ "$kind" == anvil ]]; then
|
||||
expected=$(demo_resolve_command anvil) || return 1
|
||||
@@ -203,16 +205,20 @@ demo_collect_group_members() {
|
||||
}
|
||||
|
||||
demo_anchor_allows_signal() {
|
||||
local root=$1 kind=$2 leader=$3 expected_start=$4 expected_pgid=$5 identity_mode=${6:-validated} state start pgid sid
|
||||
if ! demo_read_process_identity "$leader" state start pgid sid; then return 0; fi
|
||||
[[ "$start" == "$expected_start" && "$pgid" == "$expected_pgid" && "$sid" == "$expected_pgid" ]] || return 1
|
||||
[[ "$state" == Z ]] && return 0
|
||||
[[ "$identity_mode" == raw ]] && return 0
|
||||
demo_process_has_command_line "$leader" || return 0
|
||||
if demo_command_matches "$root" "$leader" "$kind"; then return 0; fi
|
||||
if ! demo_read_process_identity "$leader" state start pgid sid; then return 0; fi
|
||||
[[ "$state" == Z ]] && return 0
|
||||
[[ "$start" == "$expected_start" && "$pgid" == "$expected_pgid" && "$sid" == "$expected_pgid" ]] || return 1
|
||||
local root=$1 kind=$2 leader=$3 expected_start=$4 expected_pgid=$5 identity_mode=${6:-validated}
|
||||
local state start pgid sid command_status attempt
|
||||
local attempts=${DEMO_ANCHOR_RECHECK_ATTEMPTS:-10} interval=${DEMO_ANCHOR_RECHECK_INTERVAL:-0.01}
|
||||
demo_is_uint "$attempts" && ((10#$attempts > 0)) || attempts=10
|
||||
[[ "$interval" =~ ^[0-9]+([.][0-9]+)?$ ]] || interval=0.01
|
||||
for ((attempt = 0; attempt < attempts; attempt++)); do
|
||||
if ! demo_read_process_identity "$leader" state start pgid sid; then return 0; fi
|
||||
[[ "$start" == "$expected_start" && "$pgid" == "$expected_pgid" && "$sid" == "$expected_pgid" ]] || return 1
|
||||
[[ "$state" == Z ]] && return 0
|
||||
[[ "$identity_mode" == raw ]] && return 0
|
||||
if demo_command_matches "$root" "$leader" "$kind"; then return 0; else command_status=$?; fi
|
||||
((command_status == 2)) || return 1
|
||||
if ((attempt + 1 < attempts)); then sleep "$interval"; fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
@@ -221,10 +227,11 @@ demo_signal_member() {
|
||||
if ! demo_read_process_identity "$pid" state start pgid sid; then return 0; fi
|
||||
[[ "$state" != Z ]] || return 0
|
||||
[[ "$start" == "$expected_start" && "$pgid" == "$expected_pgid" && "$sid" == "$expected_sid" ]] || return 2
|
||||
if kill -"$signal" -- "$pid"; then return 0; else signal_status=$?; fi
|
||||
if kill -"$signal" -- "$pid" 2>/dev/null; then return 0; else signal_status=$?; fi
|
||||
if ! demo_read_process_identity "$pid" state start pgid sid; then return 0; fi
|
||||
[[ "$state" != Z ]] || return 0
|
||||
[[ "$start" == "$expected_start" && "$pgid" == "$expected_pgid" && "$sid" == "$expected_sid" ]] || return 0
|
||||
printf 'Failed to signal unchanged live PID %s with %s\n' "$pid" "$signal" >&2
|
||||
return "$signal_status"
|
||||
}
|
||||
|
||||
@@ -255,13 +262,19 @@ demo_stop_owned_session() {
|
||||
for member in "${members[@]}"; do
|
||||
IFS=: read -r member_pid member_start <<<"$member"
|
||||
[[ "$member_pid" != "$leader" ]] || continue
|
||||
demo_anchor_allows_signal "$root" "$kind" "$leader" "$expected_start" "$expected_pgid" "$identity_mode" || return 1
|
||||
if ! demo_anchor_allows_signal "$root" "$kind" "$leader" "$expected_start" "$expected_pgid" "$identity_mode"; then
|
||||
printf 'Refusing TERM: %s leader identity changed or remained unverifiable\n' "$kind" >&2
|
||||
return 1
|
||||
fi
|
||||
demo_signal_member "$member_pid" "$member_start" "$expected_pgid" "$expected_pgid" TERM || return 1
|
||||
done
|
||||
for member in "${members[@]}"; do
|
||||
IFS=: read -r member_pid member_start <<<"$member"
|
||||
[[ "$member_pid" == "$leader" ]] || continue
|
||||
demo_anchor_allows_signal "$root" "$kind" "$leader" "$expected_start" "$expected_pgid" "$identity_mode" || return 1
|
||||
if ! demo_anchor_allows_signal "$root" "$kind" "$leader" "$expected_start" "$expected_pgid" "$identity_mode"; then
|
||||
printf 'Refusing TERM: %s leader identity changed or remained unverifiable\n' "$kind" >&2
|
||||
return 1
|
||||
fi
|
||||
demo_signal_member "$member_pid" "$member_start" "$expected_pgid" "$expected_pgid" TERM || return 1
|
||||
done
|
||||
for ((result = 0; result < ${DEMO_TERM_WAIT_ATTEMPTS:-50}; result++)); do
|
||||
|
||||
Reference in New Issue
Block a user