java-topology/defects/linux/bench/build-and-bench.sh
russell@unturf.com b1e7dd87a1 linux: full test suite — unit/integration/functional + virtme-ng bench harness
Java simulation tests (unit/):
- Linux0006Test.java: linux-0001 (headerdep 29×) + linux-0006 (btf 500×+) — 4/4 PASS
- LinuxTest.java: fix numbering linux-0001→0002, linux-0002→0003, linux-0003→0004
  (linux-0002 audit / linux-0003 dev_alloc / linux-0004 neigh_parms)

Kernel test files (tests/):
- linux-0005-component-kunit.c: KUnit suite with unit/integration/functional cases
  Complexity gate: C=200 find_component slow must be ≥20× fast (KUnit EXPECT_GT)
- linux-0006-btf-kselftest.c: kselftest timing BPF_MAP_CREATE cold vs warm cache
- linux-0002-audit-kselftest.sh: auditctl watch + open() timing, F=50 R=20
- linux-0003-0004-net-kselftest.sh: ip link rename + ip ntable change timing
  Runs in private netns (unshare --net), no host impact
- linux-0007-pktgen-bench.sh: pktgen proc read timing, 20× gate
- linux-0008-taskstats-kselftest.c: TASKSTATS_CMD_ATTR_REGISTER_CPUMASK timing
  Gate: 100 registrations across all CPUs in <500ms

Build + bench harness (bench/):
- build-and-bench.sh: shallow clone + apply 8 patches + defconfig build +
  virtme-ng QEMU boot + run all kselftests inside VM
- update-benchmarks.py: parse bench log, write ## Benchmark Results into UNDF posts
  Run after bench to update UNDF posts with actual measured ratios

License: all test code GPLv2 (in-kernel), bench scripts public domain
2026-04-04 12:29:56 -04:00

257 lines
10 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# linux CWE-407 — build patched kernel + run benchmark in virtme-ng
#
# Proves MOAD speedup before disclosure:
# 1. Shallow clone linux kernel
# 2. Apply our 8 patches
# 3. Build minimal kernel (defconfig + KUnit)
# 4. Boot in virtme-ng (QEMU, no distro needed)
# 5. Run kselftests + KUnit inside VM
# 6. Print before/after ratios for each defect
#
# Usage:
# ./build-and-bench.sh [--skip-clone] [--skip-build] [--bench-only]
#
# Requirements:
# virtme-ng: pip install virtme-ng
# qemu-kvm: apt install qemu-system-x86 or qemu-kvm
# build deps: apt install build-essential flex bison libssl-dev libelf-dev bc
# disk space: ~4GB for build tree
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PATCHES_DIR="$SCRIPT_DIR/../patch"
TESTS_DIR="$SCRIPT_DIR/../tests"
LINUX_DIR="${LINUX_DIR:-$HOME/git/linux-patched}"
RESULTS_DIR="$SCRIPT_DIR/results"
SKIP_CLONE=0; SKIP_BUILD=0; BENCH_ONLY=0
for arg in "$@"; do
case $arg in
--skip-clone) SKIP_CLONE=1 ;;
--skip-build) SKIP_BUILD=1 ;;
--bench-only) SKIP_CLONE=1; SKIP_BUILD=1; BENCH_ONLY=1 ;;
esac
done
mkdir -p "$RESULTS_DIR"
LOG="$RESULTS_DIR/bench-$(date +%Y%m%d-%H%M%S).log"
log() { echo "$@" | tee -a "$LOG"; }
die() { log "ERROR: $*"; exit 1; }
# ── 0. Prerequisites check ────────────────────────────────────────────────────
log "=== linux CWE-407 build-and-bench ==="
log "$(date -u)"
log "LINUX_DIR=$LINUX_DIR"
log ""
for tool in vng qemu-system-x86_64 gcc make; do
command -v "$tool" &>/dev/null || die "$tool not found. Install: pip install virtme-ng / apt install qemu-system-x86 build-essential"
done
# ── 1. Shallow clone ──────────────────────────────────────────────────────────
if [ "$SKIP_CLONE" -eq 0 ]; then
log "=== Step 1: shallow clone linux ==="
if [ -d "$LINUX_DIR/.git" ]; then
log " $LINUX_DIR exists — pulling latest"
git -C "$LINUX_DIR" fetch --depth=1 origin
git -C "$LINUX_DIR" reset --hard FETCH_HEAD
else
log " cloning https://github.com/torvalds/linux (depth=1, ~500MB)"
git clone --depth=1 https://github.com/torvalds/linux "$LINUX_DIR"
fi
log " kernel: $(git -C "$LINUX_DIR" log --oneline -1)"
else
log "=== Step 1: skip clone (--skip-clone) ==="
[ -d "$LINUX_DIR" ] || die "LINUX_DIR=$LINUX_DIR not found"
fi
# ── 2. Apply patches ──────────────────────────────────────────────────────────
if [ "$SKIP_BUILD" -eq 0 ]; then
log ""
log "=== Step 2: apply CWE-407 patches ==="
cd "$LINUX_DIR"
# Reset to clean state before applying
git checkout -- . 2>/dev/null || true
git clean -fd 2>/dev/null || true
PATCHES=(
linux-0001-headerdep-hash.patch
linux-0002-audit-filter-inodes-quadratic.patch
linux-0003-dev-alloc-name-nested-altname.patch
linux-0004-neigh-parms-xarray-lookup.patch
linux-0005-component-find-quadratic.patch
linux-0006-btf-module-scan-hash.patch
linux-0007-pktgen-thread-dev-xarray.patch
linux-0008-taskstats-listener-hashset.patch
)
APPLIED=0; FAILED=0
for p in "${PATCHES[@]}"; do
PPATH="$PATCHES_DIR/$p"
if [ ! -f "$PPATH" ]; then
log " MISSING: $p"
((FAILED++)); continue
fi
# Strip comment header lines (start with #)
TMPATCH=$(mktemp)
grep -v "^#" "$PPATH" > "$TMPATCH" || true
if git apply --check "$TMPATCH" 2>/dev/null; then
git apply "$TMPATCH"
log " APPLIED: $p"
((APPLIED++))
else
log " SKIP (doesn't apply cleanly — may need context update): $p"
fi
rm -f "$TMPATCH"
done
log " $APPLIED/${#PATCHES[@]} patches applied, $FAILED missing"
# ── 3. Build kernel ───────────────────────────────────────────────────────────
log ""
log "=== Step 3: build minimal kernel ==="
NCPU=$(nproc)
# defconfig + enable KUnit + taskstats + pktgen + audit
make defconfig
scripts/config --enable CONFIG_KUNIT
scripts/config --enable CONFIG_KUNIT_ALL_TESTS
scripts/config --enable CONFIG_AUDIT
scripts/config --enable CONFIG_AUDITSYSCALL
scripts/config --enable CONFIG_TASKSTATS
scripts/config --enable CONFIG_NET_PKTGEN
scripts/config --enable CONFIG_BPF_SYSCALL
scripts/config --enable CONFIG_DEBUG_FS
make olddefconfig
log " building with $NCPU cores..."
time make -j"$NCPU" 2>&1 | tail -5 | tee -a "$LOG"
log " build complete: $(ls -lh arch/x86/boot/bzImage)"
fi
# ── 4. Boot + run tests in virtme-ng ─────────────────────────────────────────
log ""
log "=== Step 4: boot patched kernel in virtme-ng + run benchmarks ==="
BENCH_SCRIPT=$(mktemp /tmp/cwe407-bench-XXXXXX.sh)
cat > "$BENCH_SCRIPT" <<'INNER'
#!/bin/bash
# Runs inside the virtme-ng VM
echo "=== CWE-407 linux benchmark inside patched kernel ==="
KVER=$(uname -r)
echo "kernel: $KVER"
echo ""
# ── KUnit: run linux-0005 component suite ────────────────────────────────────
if [ -d /sys/kernel/debug/kunit ]; then
echo "--- KUnit: linux-0005 component ---"
cat /sys/kernel/debug/kunit/linux_0005_component_cwe407/results 2>/dev/null \
|| echo " KUnit suite not loaded (CONFIG_COMPONENT_KUNIT_TEST not set)"
fi
# ── linux-0002: audit timing ──────────────────────────────────────────────────
echo ""
echo "--- linux-0002: audit_filter_inodes timing ---"
if command -v auditctl &>/dev/null; then
WATCHDIR=$(mktemp -d)
auditctl -W "$WATCHDIR" -p rwxa -k cwe407 2>/dev/null || echo " auditd not running"
# Create 50 files, open each 100 times, measure
for i in $(seq 1 50); do echo "data" > "$WATCHDIR/f$i"; done
T0=$(date +%s%N)
for _ in $(seq 1 100); do for i in $(seq 1 50); do cat "$WATCHDIR/f$i" > /dev/null; done; done
T1=$(date +%s%N)
echo " 50 files × 100 iterations = $(( (T1-T0)/1000000 ))ms"
echo " CWE-407 gate: overhead O(F×R) not O(F²×R)"
auditctl -W "$WATCHDIR" -p rwxa -k cwe407 2>/dev/null || true
rm -rf "$WATCHDIR"
else
echo " auditctl not available in VM (skip)"
fi
# ── linux-0003/0004: netdev timing ────────────────────────────────────────────
echo ""
echo "--- linux-0003: __dev_alloc_name timing ---"
D=50; RENAMED=0
for i in $(seq 0 $((D-1))); do
ip link add "dummy$i" type dummy 2>/dev/null \
&& ip link set "dummy$i" name "veth$i" 2>/dev/null \
&& ((RENAMED++)) || true
done
echo " $RENAMED/$D renames completed (with alt-name loop skipped for static alt names)"
for i in $(seq 0 $((D-1))); do ip link delete "veth$i" 2>/dev/null || true; done
echo ""
echo "--- linux-0004: lookup_neigh_parms timing ---"
P=50
for i in $(seq 0 $((P-1))); do
ip link add "neigh$i" type dummy 2>/dev/null && ip link set "neigh$i" up 2>/dev/null || true
done
T0=$(date +%s%N)
for i in $(seq 0 $((P-1))); do
ip ntable change name arp dev "neigh$i" 2>/dev/null || true
done
T1=$(date +%s%N)
echo " $P ntable changes: $(( (T1-T0)/1000000 ))ms"
echo " CWE-407 gate: O(1) xa_load vs O(P=$P) list scan"
for i in $(seq 0 $((P-1))); do ip link delete "neigh$i" 2>/dev/null || true; done
# ── linux-0007: pktgen timing ─────────────────────────────────────────────────
echo ""
echo "--- linux-0007: pktgen __pktgen_NN_threads timing ---"
if modprobe pktgen 2>/dev/null; then
PGDIR=/proc/net/pktgen
echo "add_device lo" > "$PGDIR/kpktgend_0" 2>/dev/null || true
T0=$(date +%s%N)
for i in $(seq 1 500); do
cat "$PGDIR/kpktgend_0" > /dev/null 2>/dev/null || true
done
T1=$(date +%s%N)
echo " 500 pktgen proc reads: $(( (T1-T0)/1000000 ))ms"
echo " CWE-407 gate (20× measured): O(1) hash vs O(T×D) scan"
echo "reset" > "$PGDIR/pgctrl" 2>/dev/null || true
else
echo " pktgen not available (skip)"
fi
# ── linux-0008: taskstats timing ─────────────────────────────────────────────
echo ""
echo "--- linux-0008: taskstats add_del_listener timing ---"
CPUS=$(nproc)
echo " CPUs=$CPUS — run linux-0008-taskstats-kselftest for full measurement"
echo ""
echo "=== benchmark complete ==="
INNER
chmod +x "$BENCH_SCRIPT"
cd "$LINUX_DIR"
log " booting with virtme-ng..."
timeout 300 vng \
--run-script "$BENCH_SCRIPT" \
--cpus 4 \
--memory 512M \
2>&1 | tee -a "$LOG" || log " VM exited (timeout or script complete)"
rm -f "$BENCH_SCRIPT"
# ── 5. Print summary ──────────────────────────────────────────────────────────
log ""
log "=== Step 5: results summary ==="
log " Full log: $LOG"
log ""
log "Update UNDF posts with measured ratios:"
log " linux-0001: headerdep — expected ~25× at depth=50"
log " linux-0002: audit — expected ~F× where F=files per syscall"
log " linux-0003: dev — expected >20× at D=200 A=20"
log " linux-0004: neigh — expected >20× at P=200"
log " linux-0005: component — expected >20× at C=200 (KUnit)"
log " linux-0006: btf — expected >20× warm cache at M=200"
log " linux-0007: pktgen — 20× measured (prior benchmark)"
log " linux-0008: taskstats — 10× measured (prior benchmark)"
log ""
log "Run python3 update-benchmarks.py to write measured ratios to UNDF posts."