β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-4050

adjust_display_pll_v2 never executes the AdjustDisplayPll BIOS command (missing EXEC block; always returns BP_RESULT_FAILURE)

Summary

adjust_display_pll_v2 fills the PS inputs and returns BP_RESULT_FAILURE without calling EXEC_BIOS_CMD_TABLE or processing the output - the v3 sibling shows the intended shape. On crev-2 AdjustDisplayPll VBIOSes the handler is selected and unconditionally fails; the caller degrades gracefully so BIOS-side PLL/SS adjustment is silently skipped. Functional defect, no memory unsafety. Restore the v3-shaped EXEC block.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4050 Β· 5 files
FileTypeDescriptionSize
README.md β€” 2.4 KB ↓ raw
VERDICT.md β€” 1.8 KB ↓ raw
fix.diff β€” 925 B view raw
manifest.json β€” 667 B view raw
verdict.json β€” 2.2 KB view raw

DF-4050 β€” adjust_display_pll_v2 never executes the AdjustDisplayPll BIOS command (always returns BP_RESULT_FAILURE)

What

sys/dev/drm/amd/display/dc/bios/command_table.c:1457-1477:

static enum bp_result adjust_display_pll_v2(
    struct bios_parser *bp,
    struct bp_adjust_pixel_clock_parameters *bp_params)
{
    enum bp_result result = BP_RESULT_FAILURE;
    ADJUST_DISPLAY_PLL_PS_ALLOCATION params = { 0 };

    /* We need to convert from KHz units into 10KHz units and then convert
     * output pixel clock back 10KHz-->KHz */
    uint32_t pixel_clock_10KHz_in = bp_params->pixel_clock / 10;

    params.usPixelClock = cpu_to_le16((uint16_t)(pixel_clock_10KHz_in));
    params.ucTransmitterID = ...;
    params.ucEncodeMode = ...;
    return result;                       /* <-- EXEC block missing */
}

The function fills the input parameters and returns. There is no EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params) call, no reading of the output (sOutput.ulDispPllFreq/ucRefDiv/ucPostDiv), and no assignment to bp_params->adjusted_pixel_clock β€” the v3 sibling right below (:1479-1530) shows what the complete function must look like, and the stale comment about "convert output pixel clock back 10KHz-->KHz" refers to processing that is not there. Compare upstream Linux, where adjust_display_pll_v2 executes the command and computes bp_params->adjusted_pixel_clock via div_u64 exactly like the v3 variant.

Consequences on any VBIOS whose AdjustDisplayPll declares crev 2: bp->cmd_tbl.adjust_display_pll is wired to this function (command_table.c:1440-1455), every call returns BP_RESULT_FAILURE, and the caller (pll_adjust_pix_clk, sys/dev/drm/amd/display/dc/dce/dce_clock_source.c:444-451) degrades gracefully (skips the BIOS-adjusted clock), so the functional effect is silently-unadjusted PLL settings (SS ratio/dividers not applied) rather than memory corruption.

Impact

Functional/dead-code defect in a security-relevant parser: no memory unsafety, no leak; clock programming quality regression on hypothetical crev-2 BIOSes on supported ASICs. Info severity, confidence likely (upstream comparison from memory β€” network reference unavailable during the audit; the in-tree evidence β€” truncated function vs its v3 sibling + stale comment + unused-by-design flow β€” is unambiguous).

Fix

Restore the missing execution block, mirroring the v3 shape (see fix.diff).

Verification

Source-level; not runnable (hardware-gated, no AMD GPU). Status: untested.

VERDICT.md
↓ download raw

DF-4050 VERDICT β€” dead EXEC in adjust_display_pll_v2

Status: untested (source-certain dead path; Info severity)

  • command_table.c:1457-1477: adjust_display_pll_v2 fills ADJUST_DISPLAY_PLL_PS_ALLOCATION inputs (:1468-1475) and immediately return result; (:1476) with result == BP_RESULT_FAILURE. There is no EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, params) and no output processing (bp_params->adjusted_pixel_clock / reference_divider / pixel_clock_post_divider are never written), while the comment at :1464-1465 ("convert output pixel clock back 10KHz-->KHz") refers to exactly that missing processing, and the v3 sibling at :1479-1530 shows the complete shape including the pixel_clk_10KHz_in != 0 guard.
  • Wired and reachable: init_adjust_display_pll (:1440-1455) selects v2 when BIOS_CMD_TABLE_PARA_REVISION(AdjustDisplayPll) returns 2; the bios_parser wrapper (bios_parser.c:753-757) NULL-checks the slot but not the result; the caller degrades gracefully on FAILURE (dce_clock_source.c:444-451).
  • Impact: functional only (BIOS-side PLL adjustment silently skipped for crev-2 AdjustDisplayPll tables; SS-adjusted clocks not applied). No memory safety, no leak. Info.
  • Confidence likely rather than certain only because the upstream-diff reference was unavailable offline; every in-tree signal (truncated body, stale comment, v2/v3 asymmetry) says dropped code.
  • Not verified at runtime: hardware-gated. Status untested.

Fix status (batch validation)

Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.

Fix verification

not_testable
baseline no→ patch + rebuild →patched clean

Hardware-gated; fix restores the v3-shaped execution block, source-level only.

findings/poc/DF-4050/fix.diff
↓ fix.diffper-fix-DF-4050

Confirmed kernel references

Detail

Evidence (decisive lines)

README.md/VERDICT.md with the function quote and v2/v3 contrast

Verified recommended fix

Restore the EXEC + output-processing block mirroring adjust_display_pll_v3 (see fix.diff)

Verdict

adjust_display_pll_v2 (command_table.c:1457-1477) fills the ADJUST_DISPLAY_PLL_PS_ALLOCATION inputs and returns BP_RESULT_FAILURE without ever calling EXEC_BIOS_CMD_TABLE(AdjustDisplayPll, ...) or processing the output - the stale comment at :1464-1465 ('convert output pixel clock back 10KHz-->KHz') refers to the missing processing and the v3 sibling (:1479-1530, complete with the pixel_clk_10KHz_in != 0 guard) shows the intended shape. On crev-2 AdjustDisplayPll VBIOSes the handler is selected by init_adjust_display_pll (:1440-1455) and then unconditionally fails, so the BIOS-side PLL adjustment is silently skipped (dce_clock_source.c:444-451 degrades gracefully). Functional/dead-code defect, no memory unsafety; Info severity. Confidence 'likely' only because the upstream Linux reference was unreachable during the audit (offline); all in-tree signals indicate dropped code. Not runtime-verified: hardware-gated (no AMD GPU).