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

id_to_offset GPIO_ID_DDC_DATA hardwires the DDC6DATA bit-8 mask (0x100) for every line including the I2C pad, whose SDA field is bit 1 (0x2) β€” translate and factory tables disagree; the pin would be driven on the wrong GPIO bit

Summary

The mask is assigned once outside the per-line switch: correct for DDC1-6/VGA but wrong for I2C_PAD (SDA at bit 1; the factory's own ddc_i2c_data_regs uses the SDA mask). Latent (the consumer is dead API). Harness-proven exactly one WRONG-BIT line; per-line-mask fix.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-4947 Β· 8 files
FileTypeDescriptionSize
README.md β€” 1.0 KB ↓ raw
VERDICT.md β€” 2.7 KB ↓ raw
harness_mask.c β€” 5.8 KB view raw
build.log β€” 703 B view raw
run.log β€” 703 B view raw
fix.diff β€” 1.7 KB view raw
manifest.json β€” 758 B view raw
verdict.json β€” 3.2 KB view raw

DF-4947 β€” DCN10 id_to_offset hands the I2C pad the DDC6DATA mask (wrong GPIO bit)

File: sys/dev/drm/amd/display/dc/gpio/dcn10/hw_translate_dcn10.c:211-212,235-237 Family: DF-4944 (dce80 mask-vs-index) β€” this is the DCN10 twin. Severity: Info Β· CWE-697 (plus latent CWE-1298 wrong-bit programming)

Build

gcc -O2 -Wall -Wextra -o harness_mask harness_mask.c

Run

./harness_mask

Expected

id_to_offset(GPIO_ID_DDC_DATA, GPIO_DDC_LINE_I2C_PAD) pairs offset = REG(DC_GPIO_I2CPAD_A) (0x5dc1) with mask = 0x100 (the DDC6DATA bit-8 layout), but DC_GPIO_I2CPAD_A's SDA field is bit 1 (0x2) (dcn_1_0_sh_mask.h:41219) and the factory's own ddc_i2c_data_regs entry for this pin uses that SDA_A_MASK (ddc_regs.h:69-71). Exactly 1 WRONG BIT line; DDC1-6/VGA (identical bit-8/bit-0 layout to DDC6) and the SCL clock mask are coincidentally correct. The sole in-tree consumer (dal_gpio_get_pin_info, gpio_base.c:140-147) currently has no callers, so the defect is latent.

VERDICT.md
↓ download raw

DF-4947 VERDICT β€” reproduced (deterministic unit-level; latent β€” no in-tree consumer)

Defect

id_to_offset's GPIO_ID_DDC_DATA branch (hw_translate_dcn10.c:211-212) sets info->mask = DC_GPIO_DDC6_A__DC_GPIO_DDC6DATA_A_MASK (0x100) before the per-line switch and never changes it, so every DDC line β€” including GPIO_DDC_LINE_I2C_PAD (hw_translate_dcn10.c:235-237) β€” receives the DDC6 bit-8 layout mask. For DDC1..6 and VGA that is correct by coincidence: DC_GPIO_DDC{1..6,VGA}DATA_A_MASK are all 0x100 and the CLK masks all 0x1 (dcn_1_0_sh_mask.h:40628,40817-40818,40853-40854).

The I2C pad is different silicon: DC_GPIO_I2CPAD_A exposes DC_GPIO_SCL_A at bit 0 (0x1) and DC_GPIO_SDA_A at bit 1 (0x2) (dcn_1_0_sh_mask.h:41216-41219). The factory's own table for the same pin β€” ddc_i2c_data_regs via DDC_GPIO_I2C_REG_LIST_ENTRY(A, SDA) (ddc_regs.h:66-71) β€” uses DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK. The two tables disagree: id_to_offset would drive/read bit 8 of the I2C pad register instead of the SDA line. (DDC_CLOCK + I2C_PAD gets 0x1 == SCL_A β€” correct by coincidence.)

Result (run.log)

harness_mask (verbatim copies of hw_translate_dcn10.c:210-274, real DCN10 constants): id_to_offset(DDC_DATA, I2C_PAD) = true offset=0x5dc1 mask=0x100 real field mask=0x2 WRONG BIT (DF-4947) β€” exactly 1 wrong-mask line; the DDC1/VGA/SCL lines report OK. Deterministic.

Reachability (why Info)

The only in-tree consumer of id_to_offset is dal_gpio_get_pin_info (gpio_base.c:140-147); rg dal_gpio_get_pin_info across sys/dev/drm returns no callers. The mask defect is therefore latent today (the factory path β€” define_ddc_registers β€” is what actually programs the pins, and it uses the correct per-pin tables). If dal_gpio_get_pin_info is ever wired up (it is part of the exported gpio interface), the I2C pad would be driven on the wrong bit. Info severity, matching the DF-4944 family precedent.

Fix validation

fix.diff moves the mask assignment into the per-line switch and selects DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK for the I2C pad data line (the same edit modeled in DF-4946's harness_fixed.c, which reports mask=0x2 (SDA_A_MASK=0x2: CORRECT) and 0 residual violations). Kernel rebuild is meaningless for a userland unit harness; structural validation matches family precedent (DF-4944 fix validated the same way).

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 reproduced→ patch + rebuild →patched clean

fix.diff moves the mask selection into the per-line switch and selects DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK (0x2) for the I2C pad data line; the identical edit is modeled in DF-4946's harness_fixed.c which reports mask=0x2 CORRECT with 0 residual violations. No in-tree consumer exists today, so the patched-behavior demonstration is the unit model (family precedent DF-4944).

fix.diff (per-line mask hunks for hw_translate_dcn10.c); DF-4946/run.log 'FIXED T3: I2C_PAD data mask is now the real SDA field ... CORRECT'.
↓ fix.diffper-fix-DF-4947

Confirmed kernel references

Detail

Evidence (decisive lines)

run.log line 'id_to_offset(DDC_DATA, I2C_PAD) = true offset=0x5dc1 mask=0x100 real field mask=0x2 WRONG BIT (DF-4947)' plus the three OK lines proving the DDC6 layout masks are correct for DDC1-6/VGA/SCL; DF-4946/run.log 'FIXED T3' shows the fixed model selecting mask=0x2 CORRECT.

PoC changes

n/a β€” fresh self-contained harness (verbatim DDC branches of the dcn10 id_to_offset, real DCN10 constants).

Verified recommended fix

Select the mask per DDC line in id_to_offset; use DC_GPIO_I2CPAD_A__DC_GPIO_SDA_A_MASK for GPIO_DDC_LINE_I2C_PAD under GPIO_ID_DDC_DATA.

Verdict

id_to_offset's GPIO_ID_DDC_DATA branch (hw_translate_dcn10.c:211-212) hardwires info->mask to the DDC6DATA bit-8 layout (0x100) for every DDC line, including GPIO_DDC_LINE_I2C_PAD (235-237). The I2C pad register DC_GPIO_I2CPAD_A exposes its data line (SDA) at bit 1 (0x2, dcn_1_0_sh_mask.h:41216-41219), and the factory's own ddc_i2c_data_regs entry for this pin uses that SDA_A_MASK (ddc_regs.h:66-71) β€” the translate and factory tables disagree, so the translate path would drive/read the wrong GPIO bit. Demonstrated deterministically on the DF guest with verbatim function copies and real DCN10 constants: run.log shows exactly one WRONG BIT line (mask=0x100 vs real 0x2); DDC1-6/VGA (identical layout) and the SCL clock mask are coincidentally correct. The sole in-tree consumer, dal_gpio_get_pin_info (gpio_base.c:140-147), has no callers today, so the defect is latent β€” Info severity, matching the DF-4944 family precedent.