#!/bin/sh
# DF-1093 static source-verification: NULL+1 deref in ppb_pnp_detect.
set +e
PASS=0; FAIL=0
check() {
	if eval "$2"; then
		echo "PASS  $1"
		PASS=$((PASS+1))
	else
		echo "FAIL  $1"
		FAIL=$((FAIL+1))
	fi
}

P=sys/bus/ppbus/ppbconf.c

# 1. search_token returns NULL on miss
check "search_token returns NULL on no-match" \
	'awk "/^search_token/,/^}/" '"$P"' | grep -q "return (NULL);"'

# 2. UNKNOWN_LENGTH mode scans to next NUL
check "search_token UNKNOWN_LENGTH scans to next NUL" \
	'awk "/UNKNOWN_LENGTH/,/^}/" '"$P"' | grep -q "for (slen = 0, p = str; \*p != .\\\\0.; p++)"'

# 3-8. The six NULL+1 sites
check "site 1 (MFG): search_token(..., :) + 1 unguarded" \
	'grep -q "search_token(token, UNKNOWN_LENGTH, \":\") + 1" '"$P"''

# Count how many of these unguarded +1 sites exist (should be 6 unpatched)
SITES=$(grep -c "search_token(token, UNKNOWN_LENGTH, \":\") + 1" "$P")
echo "INFO: unguarded search_token(..., :) + 1 sites = $SITES (expected 6 unpatched, 0 patched)"

check "site count matches unpatched (6 sites)" \
	'[ "$SITES" = "6" ]'

# 4. ppb_pnp_detect is called from ppbus attach
check "ppb_pnp_detect reachable from ppbus attach" \
	'grep -q "ppb_pnp_detect" '"$P"''

# 5. ppbus is in the GENERIC kernel
check "ppbus module configured in GENERIC" \
	'grep -qE "^device\s+ppbus|device\s+ppbus" sys/config/X86_64_GENERIC || grep -q "bus/ppbus/ppbconf.c" sys/conf/files'

# 6. kprintf("%s", ...) dereferences the arg
check "kprintf format uses %s (would deref NULL+1)" \
	'grep -qE "kprintf.*<%s" '"$P"''

echo
echo "PASS=$PASS FAIL=$FAIL"
