⬢ DragonFlyBSD Kernel Audit
DF-5137 / check_static.sh
← back to finding ↓ download raw
#!/bin/sh
# DF-5137 static proof: kv_notify_message_to_smu() fail-open response
# validation in the RADEON Kaveri SMC path (radeon twin of DF-5132).
#
# Usage: sh check_static.sh <repo-root>
# Exits non-zero if any assertion fails.
ROOT="${1:-/home/maxx/dfbsd/dfbsd}"
fail=0

ck() { # ck <name> <file> <grep-args...>
    name="$1"; file="$2"; shift 2
    if grep -q "$@" "$ROOT/$file"; then
        echo "PASS $name"
    else
        echo "FAIL $name"; fail=1
    fi
}

# 1. 0x01 is the ONLY success code in the radeon PPSMC result enum.
ck "ppsmc_OK_is_1"        sys/dev/drm/radeon/ppsmc.h -e 'define PPSMC_Result_OK             ((uint8_t)0x01)'
ck "ppsmc_Failed_is_255"  sys/dev/drm/radeon/ppsmc.h -e 'define PPSMC_Result_Failed         ((uint8_t)0xFF)'

# 2. The kv wait loop polls for any non-zero response => 0x0000 means
#    "no response yet" (timeout / wedged SMC), it cannot be a success code.
ck "kv_waits_for_nonzero" sys/dev/drm/radeon/kv_smc.c -F -e 'if ((RREG32(SMC_RESP_0) & SMC_RESP_MASK) != 0)'

# 3. The validator rejects ONLY 0xFF and 0xFE and falls through to
#    "return 0" for every other value, including the 0x0000 timeout state.
ck "kv_only_rejects_FF"   sys/dev/drm/radeon/kv_smc.c -F -e 'if (tmp == 0xFF)'
ck "kv_only_rejects_FE"   sys/dev/drm/radeon/kv_smc.c -F -e 'else if (tmp == 0xFE)'
ck "kv_fallthrough_ret0"  sys/dev/drm/radeon/kv_smc.c -F -e '		return -EINVAL;
	}

	return 0;
}

int kv_dpm_get_enable_mask'

# 4. radeon's SMC_RESP_MASK is 0xffff, so the response is 16 bits wide and
#    the literal comparisons only match 0x00FF/0x00FE: a 0xFF00 (byte-swapped
#    FAILED), 0x0000 (timeout) or any undefined 0x0002..0xFFFD returns 0.
ck "resp_mask_is_16bit"   sys/dev/drm/radeon/cikd.h -F -e '#define		SMC_RESP_MASK				0xffff'

# 5. Contrast, same driver, same file family: si/rv770 return the RAW
#    response so their callers observe a timeout as failure.
ck "si_returns_raw"       sys/dev/drm/radeon/si_smc.c -F -e 'return (PPSMC_Result)tmp;'
ck "rv770_returns_raw"    sys/dev/drm/radeon/rv770_smc.c -F -e 'result = (PPSMC_Result)tmp;'

# 6. Reachability: kv_notify_message_to_smu is the sole SMC message channel
#    for the kv_dpm power-management state machine (37 references).
n=$(grep -cE 'kv_notify_message_to_smu|kv_smc_dpm_enable|kv_smc_bapm_enable|kv_send_msg_to_smc_with_parameter' "$ROOT/sys/dev/drm/radeon/kv_dpm.c")
if [ "$n" -ge 30 ]; then echo "PASS kv_dpm_reachability ($n refs in kv_dpm.c)"; else echo "FAIL kv_dpm_reachability ($n refs)"; fail=1; fi

# 7. kv_dpm_get_enable_mask propagates the fail-open: on ret==0 it reads the
#    ARG register as the mask, so a timed-out GetEnabledMask feeds garbage
#    SRAM data into the DPM state machine as a "valid" mask.
ck "getmask_reads_arg"    sys/dev/drm/radeon/kv_smc.c -F -e 'if (ret == 0)
		*enable_mask = RREG32_SMC(SMC_SYSCON_MSG_ARG_0);'

exit $fail