|
| 1 | +#!/bin/bash |
| 2 | +# Test script to verify Pdeathsig behavior using rootlesskit itself |
| 3 | +# This script: |
| 4 | +# 1. Uses rootlesskit to spawn a long-running process |
| 5 | +# 2. Kills the rootlesskit parent process |
| 6 | +# 3. Verifies that the child process is killed as expected |
| 7 | +# 4. Tests both with --reaper true and --reaper false |
| 8 | + |
| 9 | +source $(realpath $(dirname $0))/common.inc.sh |
| 10 | + |
| 11 | +INFO "Starting Pdeathsig test using rootlesskit..." |
| 12 | + |
| 13 | +# Function to run the test with a specific reaper setting |
| 14 | +run_test() { |
| 15 | + local reaper_setting=$1 |
| 16 | + INFO "Testing with --reaper $reaper_setting" |
| 17 | + |
| 18 | + # Create a temporary directory for test artifacts |
| 19 | + TEMP_DIR=$(mktemp -d) |
| 20 | + INFO "Created temporary directory: $TEMP_DIR" |
| 21 | + |
| 22 | + # Create a marker file that will be touched by the child process if it's still alive |
| 23 | + MARKER_FILE="$TEMP_DIR/child_still_alive" |
| 24 | + |
| 25 | + # Create a script that will be executed by rootlesskit |
| 26 | + CHILD_SCRIPT="$TEMP_DIR/child_script.sh" |
| 27 | + cat > "$CHILD_SCRIPT" << 'EOF' |
| 28 | +#!/bin/bash |
| 29 | +echo "Child process started with PID: $$" |
| 30 | +echo "Parent PID: $PPID" |
| 31 | +
|
| 32 | +# Register a trap to handle signals |
| 33 | +trap 'echo "Child received signal, exiting"; exit 1' TERM INT |
| 34 | +
|
| 35 | +# Run for 30 seconds, checking if parent is still alive |
| 36 | +for i in {1..30}; do |
| 37 | + echo "Child still running (iteration $i)..." |
| 38 | +
|
| 39 | + # Check if parent has changed (died) |
| 40 | + CURRENT_PPID=$(ps -o ppid= -p $$) |
| 41 | + if [ "$CURRENT_PPID" != "$PPID" ]; then |
| 42 | + echo "Parent changed from $PPID to $CURRENT_PPID" |
| 43 | + if [ "$CURRENT_PPID" = "1" ]; then |
| 44 | + echo "Parent is now init (PID 1), parent has died" |
| 45 | + echo "Child should be killed by Pdeathsig, but if you see this message, it wasn't" |
| 46 | + touch MARKER_FILE_PLACEHOLDER |
| 47 | + exit 1 |
| 48 | + fi |
| 49 | + fi |
| 50 | +
|
| 51 | + sleep 1 |
| 52 | +done |
| 53 | +
|
| 54 | +# If we reach here, the child wasn't killed |
| 55 | +echo "Child completed normally (this shouldn't happen if Pdeathsig is working)" |
| 56 | +touch MARKER_FILE_PLACEHOLDER |
| 57 | +EOF |
| 58 | + |
| 59 | + # Replace the placeholder with the actual marker file path |
| 60 | + sed -i "s|MARKER_FILE_PLACEHOLDER|$MARKER_FILE|g" "$CHILD_SCRIPT" |
| 61 | + chmod +x "$CHILD_SCRIPT" |
| 62 | + |
| 63 | + # Start rootlesskit with the child script |
| 64 | + INFO "Starting rootlesskit with --reaper $reaper_setting..." |
| 65 | + if [ "$reaper_setting" = "true" ]; then |
| 66 | + $ROOTLESSKIT --reaper $reaper_setting --pidns "$CHILD_SCRIPT" & |
| 67 | + else |
| 68 | + $ROOTLESSKIT --reaper $reaper_setting "$CHILD_SCRIPT" & |
| 69 | + fi |
| 70 | + ROOTLESSKIT_PID=$! |
| 71 | + INFO "Rootlesskit started with PID: $ROOTLESSKIT_PID" |
| 72 | + |
| 73 | + # Wait a moment for the child to start |
| 74 | + sleep 2 |
| 75 | + |
| 76 | + # Find the child process |
| 77 | + ROOTLESSKIT_CHILD_PID=$(pgrep -P $ROOTLESSKIT_PID) |
| 78 | + if [ -z "$ROOTLESSKIT_CHILD_PID" ]; then |
| 79 | + ERROR "Failed to find rootlesskit child process" |
| 80 | + return 1 |
| 81 | + fi |
| 82 | + INFO "Found rootlesskit child process with PID: $ROOTLESSKIT_CHILD_PID" |
| 83 | + |
| 84 | + # Kill the rootlesskit process |
| 85 | + INFO "Killing rootlesskit process (PID: $ROOTLESSKIT_PID)..." |
| 86 | + kill -9 $ROOTLESSKIT_PID |
| 87 | + |
| 88 | + # Wait a moment for the rootlesskit child to be killed |
| 89 | + sleep 2 |
| 90 | + |
| 91 | + # Check if the rootlesskit child process is still running |
| 92 | + if ps -p $ROOTLESSKIT_CHILD_PID > /dev/null; then |
| 93 | + ERROR "FAIL: Rootlesskit Child process (PID: $ROOTLESSKIT_CHILD_PID) is still running after rootlesskit parent was killed" |
| 94 | + kill -9 $ROOTLESSKIT_CHILD_PID # Clean up |
| 95 | + return 1 |
| 96 | + else |
| 97 | + INFO "PASS: Rootlesskit Child process (PID: $ROOTLESSKIT_CHILD_PID) was killed as expected" |
| 98 | + fi |
| 99 | + |
| 100 | + # Check if the marker file exists |
| 101 | + if [ -f "$MARKER_FILE" ]; then |
| 102 | + ERROR "FAIL: Marker file exists, which means the child process wasn't killed by Pdeathsig" |
| 103 | + return 1 |
| 104 | + else |
| 105 | + INFO "PASS: Marker file doesn't exist, which means the child process was killed by Pdeathsig" |
| 106 | + fi |
| 107 | + |
| 108 | + INFO "Test with --reaper $reaper_setting completed successfully!" |
| 109 | + rm -rf "$TEMP_DIR" |
| 110 | + return 0 |
| 111 | +} |
| 112 | + |
| 113 | +# Run tests with both reaper settings |
| 114 | +if ! run_test "true"; then |
| 115 | + ERROR "Test with --reaper true failed" |
| 116 | + exit 1 |
| 117 | +fi |
| 118 | + |
| 119 | +if ! run_test "false"; then |
| 120 | + ERROR "Test with --reaper false failed" |
| 121 | + exit 1 |
| 122 | +fi |
| 123 | + |
| 124 | +INFO "All tests completed successfully!" |
| 125 | +exit 0 |
0 commit comments