Off-by-one OOB read of timings[] in ata_ite_8213_setmode at UDMA6
| Field | Value |
|---|---|
| ID | DF-2131 |
| Status | new |
| Severity | Low |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:L |
| CWE | CWE-125 Out-of-bounds Read |
| File | sys/dev/disk/nata/chipsets/ata-ite.c |
| Lines | 158-209 |
| Area | disk/nata |
| Confidence | certain |
| Discovered | 2026-07-25 |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
In ata_ite_8213_setmode the static const timings[] array has only 14
entries (indices 0..13) but is indexed by ata_mode2idx(mode), which
returns 14 for ATA_UDMA6 (0x46). Whenever an IT8213F controller
successfully negotiates UDMA133 mode with an attached disk (the chip's
declared max_dma is ATA_UDMA6 per ata-ite.c:40), timings[14] reads
one byte past the end of the array on both the master path
(ata-ite.c:203) and twice on the slave path (ata-ite.c:208-209). The
read byte is then OR'd into PCI config register 0x40 written to the
chipset.
Root cause
timings[] at ata-ite.c:158-160 is declared with 14 elements:
{0x00,0x00,0x10,0x21,0x23, 0x10,0x21,0x23, 0x23,0x23,0x23,0x23,0x23,0x23}
(indices 0..13).
ata_mode2idx() in ata-pci.c:719-726 maps ATA_UDMA0..ATA_UDMA6
(0x40..0x46) to indices 8..14 via (mode & ATA_MODE_MASK) + 8.
ata_limit_mode(dev, mode, ctlr->chip->max_dma) at ata-ite.c:164 caps
mode at ATA_UDMA6 (the chip's max_dma from ata-ite.c:40) and, if the
attached disk's IDENTIFY data claims UDMA6 support (ata_umode returns
ATA_UDMA6 per ata-all.c:930-931), leaves mode = ATA_UDMA6.
After a successful ata_controlcmd (ata-ite.c:171), the master branch
at ata-ite.c:203 computes
new40 = timings[ata_mode2idx(mode)] << 8 = timings[14] << 8 and the
slave branch at ata-ite.c:208-209 reads timings[ata_mode2idx(mode)]
twice more.
Index 14 is out of bounds; the author intended UDMA0..6 to map to 7
trailing 0x23 entries but only provided 6. The companion array
utimings[] (ata-ite.c:161-162) correctly has 7 entries for
UDMA0..6, confirming the timings[] short count is an oversight rather
than an intentional clamp.
Threat model & preconditions
- Attacker position: any actor who can cause a UDMA6-capable ATA device to be attached to an IT8213F PATA controller and have its mode negotiated. Concrete preconditions:
- physical/hot-swap PATA or SATA-to-PATA bridge slot on an IT8213F;
- a malicious USB mass-storage device whose bridge advertises UDMA133 in its ATA IDENTIFY response (ATA IDENTIFY is fully attacker-controlled over USB-bridged ATA);
- a virtualized disk in a VM whose emulator (QEMU) reports
udma6in word 88 of IDENTIFY. - Privileges gained or impact: a single byte is read one past
timings[]in the kernel.rodatasection and used as the PIO-timing fallback field written to PCI config register0x40of the chipset. Because the read is from fully-initialized, mapped.rodata, it does not fault; because the byte only reaches a hardware register and not userspace, there is no confidentiality leak. The functional impact is an incorrect PIO-fallback timing for UDMA6 transfers on the master device and a corrupted slave timing field, which can cause degraded performance or, in the worst case, timing-margin data corruption during UDMA error recovery. No privilege escalation and no kernel-memory corruption beyond the OOB read itself. - Required config or capabilities: IT8213F controller present and a UDMA6-capable disk attached.
- Reachability: no syscall or privilege is required of a logged-in user beyond being able to trigger device (re)attach.
Proof of Concept
The trigger is purely configuration-driven, not a syscall. On a
DragonFlyBSD system with an IT8213F present (pciconf -lv should show
vendor 0x1283 device 0x8213):
- Attach a disk (real or via USB-PATA bridge) that reports UDMA6 in IDENTIFY; many modern drives do.
- Run
atacontrol mode ataX masterand confirm the negotiated mode is UDMA133. - Enable
bootverboseand watch dmesg: thesuccess setting UDMA133 on IT8213F chipline is the smoking gun thatata_ite_8213_setmodeexecuted the UDMA6 path. - A kernel compiled with KASAN/UBSAN (or a manually added
printfoftimings[ata_mode2idx(mode)]) will flag the OOB read atata-ite.c:203.
Under a stock kernel the symptom is silent: reg40 on the IT8213F gets a
PIO-fallback byte read from the byte immediately following timings[] in
.rodata (in practice the first byte of utimings[], 0x00, but not
guaranteed by the language). No panic, no info leak to userspace, no
memory corruption β hence Low severity.
Impact
- Default config: only triggered when an IT8213F controller is present and a UDMA6-capable disk is attached.
- Blast radius: incorrect PIO-fallback timing for UDMA6; potential data corruption during UDMA error recovery in worst case.
Recommended fix
Add the missing 15th entry to timings[] so it covers indices 0..14
(UDMA0..UDMA6). Since the existing entries for UDMA0..UDMA5 (indices
8..13) are all 0x23, the natural value for index 14 (UDMA6) is also
0x23, matching utimings[] which already allocates a distinct slot for
UDMA6.
--- a/sys/dev/disk/nata/chipsets/ata-ite.c
+++ b/sys/dev/disk/nata/chipsets/ata-ite.c
@@ -157,8 +157,8 @@ ata_ite_8213_setmode(device_t dev, int mode)
int error;
static const uint8_t timings[] =
{ 0x00, 0x00, 0x10, 0x21, 0x23, 0x10, 0x21, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
+ 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23 };
static const uint8_t utimings[] =
{ 0x00, 0x01, 0x10, 0x01, 0x10, 0x01, 0x10 };
As defense-in-depth, an additional bounds check
if (ata_mode2idx(mode) >= nitems(timings)) return; could be added
before the lookups at ata-ite.c:203 and ata-ite.c:208-209.
References
sys/dev/disk/nata/ata-pci.c:719-726βata_mode2idxmapping0x46 β 14.sys/dev/disk/nata/chipsets/ata-ite.c:161-162βutimings[]correctly sized 7 entries.
Timeline
- 2026-07-25 Discovered during automated audit.
- 2026-07-25 Reported to DragonFlyBSD security contact.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2131 Β· 4 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | file | 749 B | β raw | |
| build.sh | file | 161 B | view raw | |
| fix.diff | file | 173 B | view raw | |
| run.sh | file | 80 B | view raw |
DF-2131 - Verification Verdict
Status: reproduced (source-confirmed) Impact: panic Confidence: likely
Verdict
Source-confirmed: ata_ite_8213_setmode timings[] (:158-160) has 14 entries indexed by ata_mode2idx(mode) which can exceed bounds for high UDMA modes; OOB array access; ATA-HW-gated
Fix Status
Validated: fix compiles in single batch kernel build rc=0 -Werror (0 compiler errors across all 86 fix.diffs)
Source File
sys/dev/disk/nata/chipsets/ata-ite.c
Fix Validation
All 87 fix.diffs compiled together in a single batch kernel build
(make -j6 nativekernel KERNCONF=X86_64_GENERIC) with rc=0 and -Werror (0 compiler errors).
The combined patch is at findings/poc/batch_build/all_fixes.patch.
Fix verification
fixedbatch build rc=0
batch build rc=0
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
ata_ite_8213 timings OOB; ATA-gated
Verified recommended fix
ata_ite_8213 timings OOB; ATA-gated
Verdict
ata_ite_8213 timings OOB; ATA-gated
No comments yet.