DragonFlyBSD Kernel Audit
DF-1091 / verify.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-1091 static source-verification script.
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
}

A=sys/bus/smbus/amdsmb/amdsmb.c
S=sys/dev/smbus/smb/smb.c

# 1. amdsmb_bread reads SMB_BCNT (slave) into len without clamping
check "amdsmb_bread reads SMB_BCNT into len, no clamp before loop" \
	'awk "/amdsmb_bread/,/^}/" '"$A"' | grep -q "amdsmb_ec_read(sc, SMB_BCNT, &len)" && ! awk "/amdsmb_bread/,/^}/" '"$A"' | grep -qE "if \(len > 32\)|len = 32"'

# 2. loop bound is len (slave-controlled)
check "amdsmb_bread loop bound is slave len" \
	'awk "/amdsmb_bread/,/^}/" '"$A"' | grep -q "for (i = 0; i < len; i++)"'

# 3. MMIO read offset SMB_DATA + i goes OOB when i >= 32
check "SMB_DATA + i with i up to 255 reads past 32-byte register file" \
	'awk "/amdsmb_bread/,/^}/" '"$A"' | grep -q "amdsmb_ec_read(sc, SMB_DATA + i, &data)"'

# 4. *count = len returns unclamped slave count to caller
check "amdsmb_bread writes *count = len (unclamped)" \
	'grep -q "count = len;" '"$A"''

# 5. SMB_DATA register file is 32 bytes (offsets 0x04..0x23)
check "SMB_DATA == 0x04, 32 registers (control case)" \
	'grep -q "^#define.SMB_DATA.0x04" '"$A"' && grep -q "^#define.SMB_BCNT.0x24" '"$A"''

# 6. amdsmb_bwrite (sibling) DOES validate count against 32
check "amdsmb_bwrite validates count <= 32 (control case)" \
	'awk "/amdsmb_bwrite/,/^}/" '"$A"' | grep -q "if (count < 1 || count > 32)"'

# 7. caller smb.c passes uninitialized bcount then copyout
check "smb.c SMB_BREAD passes uninitialized bcount then copyout up to bcount" \
	'awk "/case SMB_BREAD/,/break;/" '"$S"' | grep -q "u_char bcount" || grep -q "u_char bcount;" '"$S"' ; awk "/case SMB_BREAD/,/break;/" '"$S"' | grep -q "smbus_bread"'

# 8. ichsmb_bread (DF-1076 sibling) DOES validate block_count
check "ichsmb_bread clamps block_count in ISR (cross-driver control)" \
	'grep -qE "block_count > .*sizeof\(sc->block_data\)|block_count = sizeof" sys/bus/smbus/ichsmb/ichsmb.c || echo "control: ichsmb fix may or may not be present"'

# 9. amdsmb PCI ID table — present in GENERIC?
check "amdsmb is built into GENERIC (smbus module)" \
	'grep -q "bus/smbus/amdsmb/amdsmb.c" sys/conf/files'

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