ksprintf overflows 9-byte msp/dpl version string buffers by up to 2 bytes (lands in struct padding, no impact today)
| Field | Value |
|---|---|
| ID | DF-1850 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:N/A:N |
| CWE | CWE-787 Out-of-bounds Write |
| File | sys/dev/video/bktr/bktr_audio.c |
| Lines | 442, 598 |
| Area | dev/video (bktr audio probe) |
| Confidence | certain |
| Discovered | 2026-07-20 |
| Reported | pending |
| Known CVE | none |
| CVE match | dfly_specific |
Summary
msp_read_id() and dpl_read_id() ksprintf into char[9] buffers using
format "34%02d%c-%c%d". The %02d conversion produces a minimum of 2 digits
but does NOT cap at 2 β for input value 100..255 it emits 3 digits, making total
output up to 10 chars + NUL = 11 bytes into a 9-byte buffer. The 2-byte overrun
currently lands in compiler-inserted struct padding before the adjacent int
field, so there is no security impact today, but it is undefined behavior and a
latent corruption risk if the struct is ever repacked or the field reordered.
Root cause
At bktr_audio.c:442-443, msp_read_id() calls:
ksprintf(bktr->msp_version_string, "34%02d%c-%c%d",
(rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
bktr->msp_version_string is declared char[9] at bktr_reg.h:572. The format
breakdown for worst-case I2C read (rev2=0xffff β (rev2>>8)&0xff=255,
rev2&0x1f=31):
| Part | Chars |
|---|---|
"34" |
2 |
"%02d", 255 |
3 ("255" β %02d is min-width-2, NOT max-width-2) |
"%c" |
1 |
"-" |
1 |
"%c" |
1 |
"%d", 31 |
2 |
NUL |
1 |
| Total | 11 bytes into 9-byte buffer β 2-byte overflow |
The identical pattern exists at bktr_audio.c:598-599 in dpl_read_id() writing
to char dpl_version_string[9] (bktr_reg.h:574).
The overflow bytes land at struct offsets 9 and 10. In struct bktr_softc
(bktr_reg.h:572-575) the next field after char[9] is int msp_addr (4-byte
aligned), so the compiler inserts 3 padding bytes at offsets 9-11. The overrun
is absorbed by padding. No struct is declared __packed.
Threat model & preconditions
- Attacker position: none user-reachable. The
rev1/rev2values come frommsp_dpl_read()I2C transactions against the MSP34xx/DPL35xx chip (bktr_audio.c:439-440, 595-596). These functions are only called from bktr_card.c:1263 and bktr_card.c:1277 during device probe/attach (NOT from any user ioctl path), and only afteri2cRead()confirms the chip is present. - Privileges gained or impact: none. The overflow lands in struct padding and corrupts nothing. No path exists for an unprivileged local user to trigger this.
- Required config or capabilities: malicious PCI hardware that returns
crafted I2C bytes at probe time, or a glitchy MSP chip returning
0xffff. - Reachability: device probe/attach only.
Proof of concept
Not exploitable for security impact. To demonstrate the overflow itself (requires
a Bt848/Bt878 card with an MSP34xx chip whose S/N register returns 0xffff):
- Boot a DragonFlyBSD system with such a card.
- The probe path in bktr_card.c:1263 calls
msp_read_id()which readsrev1=0xffff,rev2=0xffff. ksprintfwrites 11 bytes to the 9-bytemsp_version_string[].- Confirm with KASSERT/KASAN or by adding a
printfof output length vs buffer.
No panic, no corruption observable β bytes land in padding. Hardening/UB issue only.
Impact
Info-level undefined behavior. No memory corruption today because the overflow lands in compiler-inserted struct padding. Latent risk if the struct is ever repacked or the field reordered.
Recommended fix
Use ksnprintf with the buffer size (truncates safely), or enlarge the buffers.
--- a/sys/dev/video/bktr/bktr_audio.c
+++ b/sys/dev/video/bktr/bktr_audio.c
@@ -439,7 +439,8 @@ void msp_read_id( bktr_ptr_t bktr ){
rev2 = msp_dpl_read(bktr, bktr->msp_addr, 0x12, 0x001f);
- ksprintf(bktr->msp_version_string, "34%02d%c-%c%d",
+ ksnprintf(bktr->msp_version_string,
+ sizeof(bktr->msp_version_string), "34%02d%c-%c%d",
(rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
}
@@ -595,7 +596,8 @@ void dpl_read_id( bktr_ptr_t bktr ){
rev2 = msp_dpl_read(bktr, bktr->dpl_addr, 0x12, 0x001f);
- ksprintf(bktr->dpl_version_string, "34%02d%c-%c%d",
+ ksnprintf(bktr->dpl_version_string,
+ sizeof(bktr->dpl_version_string), "34%02d%c-%c%d",
((rev2>>8)&0xff)-1, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
}
Alternatively, enlarge both char[9] fields to char[12] in bktr_reg.h:572,574
β since 3 bytes of padding already exist before the adjacent int fields, this
costs zero additional memory and eliminates the UB entirely.
Timeline
- 2026-07-20 Discovered during automated audit.
- 2026-07-20 Reported to DragonFlyBSD security contact (pending).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1850 Β· 1 files| File | Type | Description | Size | |
|---|---|---|---|---|
| fix.diff | suggested-fix | ksprintf overflows 9-byte msp/dpl version string buffers by up to 2 bytes (lands | 690 B | view raw |
Fix verification
fixedfix.diff applied + combined nativekernel build rc=0 (-Werror)
fix.diff applied + combined nativekernel build rc=0 (-Werror)
Confirmed kernel references
β
Detail
Exploit chain
none (Info severity)
Evidence (decisive lines)
Source-confirmed at sys/dev/video/bktr/bktr_audio.c:442: ksprintf overflows 9-byte msp/dpl version string buffers by up to 2 bytes
Verified recommended fix
Source-confirmed at sys/dev/video/bktr/bktr_audio.c:442: ksprintf overflows 9-byte msp/dpl version string buffers by up to 2 bytes
Verdict
Source-confirmed at sys/dev/video/bktr/bktr_audio.c:442: ksprintf overflows 9-byte msp/dpl version string buffers by up to 2 bytes
No comments yet.