Stack buffer overflow: 32-byte buf[] used for GSBUS BLOCK/BYTES transfers carrying up to 255 bytes
Summary
smbus_acpi_space_handler at smbacpi.c:137 declares char buf[32] for all GSBUS protocol transfers. ACPICA allocates 257-byte buffers (2-byte header + ACPI_MAX_GSBUS_DATA_SIZE=255 data) for ATTRIB_BLOCK(0x0A) and ATTRIB_BYTES(0x0B). Three overflow paths: (1) BLOCK WRITE at :208 memcpy(buf,gsb->data,gsb->len) with gsb->len up to 255 -> 223-byte stack overflow; (2) BYTES WRITE at :223 memcpy(buf,gsb->data,info->AccessLength) with AccessLength up to 255 -> same; (3) BYTES READ at :217-219 SMBUS_TRANS with rbuf=buf rcount=info->AccessLength up to 255, ig4_iic.c smb_transaction NOCNT branch writes rcount bytes into rbuf. BLOCK READ at :199-206 NOT affected (count init 32, ig4 caps via rcount>last check). Attacker controls ACPI AML: malicious firmware, root DSDT override (acpi_dsdt_load), or malicious hypervisor guest ACPI. Overflow size and data attacker-controlled. Impact: kernel panic minimum, potential ring-0 code execution by overwriting return address.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1112 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| df1112.c | trigger-source | documentation-only source trace stub | 1.7 KB | view raw |
| build.sh | build-script | no compilation needed (latent) | 301 B | view raw |
| run.sh | run-script | no runtime trigger | 269 B | view raw |
| fix.diff | suggested-fix | resize buf[] to ACPI_MAX_GSBUS_DATA_SIZE+1 (256 bytes) | 741 B | view raw |
| VERDICT.md | verdict | full source-level trace + Phase 6 hard-blocker analysis | 3.6 KB | β raw |
| README.md | readme | claim summary + reproducibility notes | 2.2 KB | β raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-1112 β Stack buffer overflow in smbus_acpi_space_handler (GSBUS)
Claim
smbus_acpi_space_handler() at sys/bus/smbus/smbacpi/smbacpi.c:137 declares
char buf[32] for all GSBUS (ACPI GenericSerialBus) protocol transfers.
ACPICA allocates 257-byte buffers for ATTRIB_BLOCK(0x0A) and
ATTRIB_BYTES(0x0B) transfers (2-byte header + ACPI_MAX_GSBUS_DATA_SIZE
of 255 data bytes) β see contrib/dev/acpica/source/components/events/evhandler.c
and evxface.c. Three overflow paths exist:
- BLOCK WRITE at smbacpi.c:208:
memcpy(buf, gsb->data, gsb->len)withgsb->lenup to 255 β up to 223-byte stack overflow. - BYTES WRITE at smbacpi.c:223:
memcpy(buf, gsb->data, info->AccessLength)withinfo->AccessLengthup to 255 β same magnitude. - BYTES READ at smbacpi.c:217-219:
SMBUS_TRANS(..., buf, info->AccessLength, ...)withinfo->AccessLengthup to 255. Theig4_iic.csmb_transactionNOCNT branch writesrcountbytes intorbufβ same overflow magnitude.
BLOCK READ (smbacpi.c:199-206) is NOT affected β count is initialised to
32 (line 200) and ig4_iic.c caps via its rcount > last check.
The attacker controls the ACPI AML: malicious firmware, a root DSDT override
(acpi_dsdt_load), or a malicious hypervisor guest ACPI.
Reproducibility on this guest
The audit guest's firmware (BOCHS BXPC) does not ship any GSBUS OpRegion in
its DSDT (ACPI: DSDT 0x00000000BFFE0040 001AF8 β 0x1AF8 bytes, only
standard devices). smbus_acpi_space_handler is registered only if a
smbus device attaches under an ACPI-enumerated I2C controller with a GSBUS
opregion declaration; on this guest there is none, so the handler is never
invoked. Verified:
$ dmesg | grep -iE 'smbus|ig4|smbacpi' (empty)
The bug is latent β confirmed by source trace. A realistic runtime
trigger would require either malicious firmware, a malicious hypervisor
controlling guest ACPI, or root triggering acpi_dsdt_load with a crafted
DSDT override. None of those is an unprivileged attack surface on this
guest.
Fix
fix.diff: size buf[] to match the maximum GSBUS data size
(ACPI_MAX_GSBUS_DATA_SIZE + 1 = 256) so the buffer can hold any ACPICA
buffer without overflow.
DF-1112 β VERDICT
Verdict: NOT REPRODUCED at runtime (latent β requires ACPI AML with a GSBUS opregion; the BOCHS firmware DSDT has none, and the smbus_acpi driver never attaches). Bug confirmed by source trace.
Mechanism (source-confirmed)
smbus_acpi_space_handler() at sys/bus/smbus/smbacpi/smbacpi.c:137
declares char buf[32] for all GSBUS (ACPI GenericSerialBus) protocol
transfers.
ACPICA allocates 257-byte buffers (2-byte header +
ACPI_MAX_GSBUS_DATA_SIZE = 255 data bytes β see
sys/contrib/dev/acpica/source/include/acconfig.h:332) for
ATTRIB_BLOCK(0x0A) and ATTRIB_BYTES(0x0B) transfers and passes the
data portion to this handler. Three overflow paths:
- BLOCK WRITE at smbacpi.c:208:
memcpy(buf, gsb->data, gsb->len)withgsb->lenup to 255 β up to 223-byte stack overflow. - BYTES WRITE at smbacpi.c:223:
memcpy(buf, gsb->data, info->AccessLength)withinfo->AccessLengthup to 255 β same magnitude. - BYTES READ at smbacpi.c:217-219:
SMBUS_TRANS(..., buf, info->AccessLength, ...)withinfo->AccessLengthup to 255; theig4_iic.csmb_transactionNOCNT branch writesrcountbytes intorbufβ same overflow magnitude.
BLOCK READ (smbacpi.c:199-206) is not affected β count is
initialised to 32 at line 200 and ig4_iic.c caps via its
rcount > last check.
The attacker controls the ACPI AML. Trigger surfaces:
- malicious / buggy firmware,
- root-triggered DSDT override via acpi_dsdt_load,
- a malicious hypervisor controlling guest ACPI.
Why it can't be triggered on this guest
$ dmesg | grep -iE 'smbus|ig4|smbacpi' (empty)
The BOCHS firmware DSDT is 0x1AF8 bytes and contains only standard
devices (no GSBUS opregion declaration). The smbus_acpi driver never
attaches because there is no ACPI-enumerated I2C controller with a GSBUS
opregion on this guest, so smbus_acpi_space_handler is never even
registered with ACPICA, let alone invoked.
Even with a malicious DSDT loaded via acpi_dsdt_load, the trigger
requires root (loading a DSDT is a privileged action), so this is not
an unprivileged attack surface.
Exploit chain
Primitive class: stack buffer overflow (up to ~223 bytes) with both
size and content controlled by attacker-controlled ACPI AML. On a kernel
without stack protector for this path (and KASLR off), this could in
principle overwrite the return address β control-flow hijack β
commit_creds(prepare_kernel_cred(0)) chain.
BUT:
- The trigger requires either malicious firmware or a
rootDSDT override. Rootβkernel is game-over by definition; there is no privilege boundary to cross. - The handler is never invoked on this guest.
Valid hard blocker ("vulnerable code path is dead code at runtime on
this guest AND no harness can exercise it without hardware/firmware the
guest lacks"). Documented as latent. No uid=0 achievable from an
unprivileged context on this guest.
Fix
fix.diff resizes buf[] from char buf[32] to
char buf[ACPI_MAX_GSBUS_DATA_SIZE + 1] (= 256 bytes), large enough to
hold any ACPICA GSBUS data payload without overflow. This matches
ACPICA's own buffer sizing. Validated as applies + compiles in a clean
GENERIC kernel build.
Fix validation
not_testable β path not runtime-reachable on this guest. Validated
fix.diff applies cleanly and compiles with -Werror in a full
make nativekernel KERNCONF=X86_64_GENERIC (smbacpi.o rebuilt fresh, no
warnings/errors β see ../DF-1096/all_fixes_build.log).
PoC changes
- Wrote
df1112.c(documentation-only stub explaining the source trace). - Wrote
fix.diff,build.sh,run.sh.
Fix verification
not_testablecompile validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. smbus_acpi GSBUS buf[32] vs ACPICA 257B -> stack overflow. No GSBUS opregion. Compile validated.
No comments yet.