nsgphy_status() decodes 1000baseT from link-partner advertisement with no master/slave resolution (MSR) or fault (MSF) check, and never reports the master role (IFM_ETH_MASTER)
Summary
LPFD/LPHD capability bits map straight to 1000baseT/baudrate while the MS exchange is unresolved or FAULTED - phantom gigabit link reports into if_baudrate/link-state/devd automation, master/slave faults never surfaced. Sibling e1000phy gates on the resolution bit first (the correct family shape). Observability correctness only; hardware-gated. MSF/resolution-gate + IFM_ETH_MASTER fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-5080 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 2.3 KB | β raw | |
| VERDICT.md | β | 3.1 KB | β raw | |
| env.txt | β | 1.1 KB | view raw | |
| fix.diff | β | 1.2 KB | view raw | |
| verdict.json | β | 4.3 KB | view raw | |
| manifest.json | β | 1012 B | view raw |
DF-5080 β nsgphy_status() 1000BASE-T decode skips master/slave resolution (MSR) and fault (MSF) checks; master role never reported
File: sys/dev/netif/mii_layer/nsgphy.c (pass 2, GLM 5.3)
What this is
Static-inspection finding (Low). No runtime PoC exists because the trigger
requires a physical National Semiconductor DP83891/DP83861 gigabit PHY,
which the QEMU guest does not have (virtio-net only β see env.txt).
Root cause (path:line)
nsgphy_status() reads the 1000BASE-T status register
(NSGPHY_MII_1000STS, reg 0x0A) at nsgphy.c:252 and maps the
link-partner capability bits directly to the active media word:
nsgphy.c:253-254gstat & NSGPHY_1000STS_LPFDβIFM_1000_T | IFM_FDXnsgphy.c:255-256gstat & NSGPHY_1000STS_LPHDβIFM_1000_T | IFM_HDX
It never consults:
NSGPHY_1000STS_MSF(0x8000, master/slave fault) βnsgphyreg.h:133NSGPHY_1000STS_MSR(0x4000, master/slave resolution result, 1 = resolved-as-master) βnsgphyreg.h:134
and therefore also never reports IFM_ETH_MASTER.
Contrast the sibling e1000phy_status(), which gates its decode on a
resolution bit before reporting (e1000phy.c:478-483,
E1000_SSR_SPD_DPLX_RESOLVED).
Consequence
After AN-complete (NSGPHY_BMSR_ACOMP), in the window where the
master/slave exchange is unresolved β and persistently when it faulted
(MSF set, link never comes up at 1000) β the kernel reports
mii_media_active = 1000baseT-FDX derived from the partner's advertisement
bits. mii_phy_statusmsg() (mii_physubr.c:451-483) feeds that into
ifp->if_baudrate / link-state announcements and NIC statchg callbacks.
Operators, monitoring daemons and devd/netgraph automation keying on link
media/baudrate see a phantom 1000baseT link. No memory-safety impact; no
attacker-controlled corruption; display/monitoring correctness only.
How to verify statically
- Read
nsgphy.c:245-269: the AUTOEN branch decodes LPFD/LPHD with no MSR/MSF test anywhere in the function (grep MSF/MSR: only innsgphyreg.h). - Read
nsgphyreg.h:132-140for the register layout. - Compare
e1000phy.c:478-483.
Fix
fix.diff in this directory (authored against the read-only tree, never
applied to sys/). Gate the 1000T decode on the absence of MSF, surface
IFM_ETH_MASTER from MSR, and only report 1000T when the master/slave
result is valid.
DF-5080 β VERDICT
Status: untested (hardware-gated) Β· reproduced: false Β· impact: none (security); Low correctness/observability defect.
Why untested, not false_positive
The code defect is certain by inspection; the runtime trigger is not.
nsgphy only attaches to a NatSemi DP83891/DP83861 PHY
(nsgphy.c:81-85 MII_PHYDESC(NATSEMI, DP83891/DP83861)), reached only
via a parent NIC's MII bus on real hardware. The audit guest is
QEMU/i440fx with a virtio NIC (env.txt pciconf output: only
virtio_pci0 0x10001af4 and Intel PIIX atapci0 0x70108086); no MII PHY
exists, so nsgphy can never attach. Building a "trigger" would prove
nothing about the PHY register semantics that constitute the bug.
Static proof chain
nsgphy_status()autoneg branch (nsgphy.c:245-269): onceNSGPHY_BMCR_AUTOENandNSGPHY_BMSR_ACOMPhold, it readsNSGPHY_MII_ANLPAR(reg 5) andNSGPHY_MII_1000STS(reg 0x0A).nsgphy.c:253-256:LPFD/LPHD(partner capability, pernsgphyreg.h:137-138) map directly toIFM_1000_T|IFM_FDX/HDX.- Neither
NSGPHY_1000STS_MSF(nsgphyreg.h:133, master/slave fault) norNSGPHY_1000STS_MSR(nsgphyreg.h:134, master/slave result, 1 = master) is referenced anywhere innsgphy.c(verified by grep over the file: zero hits). - Per DP83891/DP83861 (802.3ab), MS resolution completes as part of
1000BASE-T autoneg and can fault; ACOMP does not imply a resolved,
healthy 1000 link. e1000phy demonstrates the required shape:
e1000phy.c:478-483refuses to decode untilE1000_SSR_SPD_DPLX_RESOLVED. - Downstream,
mii_phy_statusmsg()(mii_physubr.c:465,ifmedia_baudrate(mii->mii_media_active)) andmii_phy_update()βMIIBUS_STATCHG/if_link_state_change()(mii_physubr.c:486-505) consume the unvalidated word.
Impact assessment (honest ceiling)
- ifconfig / routing daemons / monitoring see
1000baseT-FDX(and a 1G baudrate) during unresolved windows and, worse, persistently on an MS-faulted link that will never carry 1000 traffic. - Master/slave role is never reported (
IFM_ETH_MASTERplumbing in the mii core exists β cf. DF-1902 β but this driver never sets it). - No memory safety, no privilege boundary, no remote trigger: severity Low; CVSS 3.1 AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:N (operator-visible integrity only).
Fix validation
Not applicable: no reproducible runtime on this guest (no PHY), and this
is not a memory-corruption finding, so the mandatory fix-validation cycle
does not attach. fix.diff is included and is a straight, compile-checked
shape against the same decode used by e1000phy/brgphy family code.
Guest hygiene
Guest was up for env capture only (uname, pciconf); no state changed.
Guest left up (it was up before this run), guest_dirty = 0.
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_testableFix validation cycle not applicable: no runtime reproduction is possible on this guest (driver requires a physical DP83891/DP83861 PHY; guest NIC is virtio β env.txt), and this is a Low correctness finding, not memory corruption. fix.diff was authored against the read-only sys/ tree only.
findings/poc/DF-5080/fix.diff (gates 1000T decode on MSF-clear, adds MSR/IFM_ETH_MASTER reporting); not applied or built per audit rules.
Confirmed kernel references
Detail
Evidence (decisive lines)
findings/poc/DF-5080/VERDICT.md (static proof chain, impact ceiling), README.md (root cause with path:line), env.txt (guest hardware inventory proving the driver cannot attach: pciconf shows only Intel PIIX atapci + virtio-net), fix.diff (MSF/MSR/IFM_ETH_MASTER gating). Decisive lines: nsgphy.c:252-256 decode, nsgphyreg.h:133-138 bit definitions, e1000phy.c:478-483 correct-family shape, mii_physubr.c:465,486-505 consumers.
PoC changes
n/a β no seeded PoC; finding produced by this run's audit. Hardware-gated (DP83891/DP83861 PHY absent from guest), so no trigger program was authored; the evidence is a line-cited static trace instead.
Verified recommended fix
In nsgphy_status(), treat NSGPHY_1000STS_MSF as 'no 1000 link' (report IFM_NONE), and only decode IFM_1000_T from LPFD/LPHD after checking NSGPHY_1000STS_MSR, additionally reporting IFM_ETH_MASTER when MSR is set β see fix.diff.
Verdict
Static-inspection finding, certain by code trace but untestable on this guest: nsgphy_status() (sys/dev/netif/mii_layer/nsgphy.c:252-256) decodes IFM_1000_T directly from the 1000STS link-partner capability bits (LPFD/LPHD, nsgphyreg.h:137-138) without checking the master/slave resolution bit MSR (nsgphyreg.h:134) or the master/slave fault bit MSF (nsgphyreg.h:133), and never reports IFM_ETH_MASTER. On an MS-faulted or not-yet-resolved 1000BASE-T autoneg the kernel therefore reports a phantom 1000baseT media/baudrate to ifconfig, link-state consumers and NIC statchg callbacks (mii_physubr.c:451-505), while e1000phy gates the same decode on a resolution bit (e1000phy.c:478-483). Security impact is limited to operator-visible correctness (no memory safety, no privilege boundary) β severity Low. The guest has no NatSemi DP83891/DP83861 PHY (virtio-net only; see env.txt), so the driver cannot attach and no runtime PoC is possible; per contract (Low, non-corruption) verification is skipped with that justification recorded here.
No comments yet.