Skip to content

Zero DMA destination buffer on server WRITE_PRE#486

Open
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:mainfrom
yosuke-wolfssl:fix/f_4238
Open

Zero DMA destination buffer on server WRITE_PRE#486
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:mainfrom
yosuke-wolfssl:fix/f_4238

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Jul 24, 2026

Copy link
Copy Markdown

Problem

WH_MESSAGE_CERT_ACTION_READTRUSTED_DMA passed req.cert_len to WRITE_POST
regardless of bytes written. On a port whose callback transfers in WRITE_POST,
an authenticated client received up to cert_len bytes of uninitialised server
memory when the read was denied (WH_ERROR_ACCESS), when the id was absent, or —
on success — past the end of a short certificate. NVM READDMA had the identical
defect, unmentioned by the report. Addressed by F-4238.

Fix (src/wh_server_cert.c)

  • Deny before mapping — the flag check and metadata lookup precede
    WRITE_PRE, so a refused request never maps client memory.
    wh_Server_CertReadTrusted() calls the unchecked wh_Nvm_Read(), so this is
    the only gate.
  • Zero-fill on WRITE_PRE — the full mapped length is zeroed before the
    read, so the tail past a short object is zeros, not residue.
  • NULL mapping / zero length — a PRE yielding no writable pointer fails
    WH_ERROR_BADARGS with no paired POST; a zero-length request stays a no-op.
  • cert_len bounded by WOLFHSM_CFG_MAX_CERT_SIZE. NVM objects have no size
    cap, so the DMA allowlist bounds that handler's write extent — stated in
    wolfhsm/wh_client.h.

src/wh_server_nvm.c gets the same deny-before-map and zero-fill. Both handlers
keep main's per-handler lock layout: NVM brackets its POST inside the lock,
cert's POST stays outside (only cert's PRE had to move in for the deny check).

Path Before After
denied / absent id cert_len of server heap never mapped
short read trailing heap disclosed zero-filled

Client-visible behavior changes:

  • denied id + out-of-range offset → WH_ERROR_ACCESS (was BADARGS), closing a
    length oracle on protected objects.
  • the full requested length is written, not the clamped read length; a short
    read zeros the tail rather than leaving prior contents.

Tests

New test-refactor/server/wh_test_dma_zerofill.c, 13 sub-tests across both
handlers and both port shapes (bounce-buffer and direct-mapped): denied/absent
id, out-of-range offset, short read, no-carry, oversized length, null address,
null mapping, zero-length no-op, allowlist accept/reject, and cert
buffer-too-small. Registered in whTestsServer[], run by 9 DMA=1 CI configs
on Linux and macOS. whTest_CryptoAesDmaInPlace guards against re-centralising
the zero-fill, which corrupts in-place AES.

Verification

  • 48/22/0 (DMA=1), 43/27/0 (plain), 49/21/0 (THREADSAFE=1 DMA=1); legacy
    suite exits 0 both ways.
  • Per-fix negative controls; rc-parity probe vs. base shows one intended delta.

@yosuke-wolfssl yosuke-wolfssl self-assigned this Jul 24, 2026
Copilot AI review requested due to automatic review settings July 24, 2026 01:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR closes a DMA bounce-buffer disclosure class in server-side DMA READ handlers by ensuring client destination buffers are either never mapped on refusal paths or are fully zero-filled before any partial writes, and it documents the resulting client-visible buffer contract.

Changes:

  • Reorders READDMA / READTRUSTED_DMA logic to deny-before-map and adds destination-buffer zero-fill on successful WRITE_PRE mappings.
  • Updates client and server header documentation to describe the destination-buffer contract and DMA callback locking constraints.
  • Adds focused regression tests for zero-fill behavior (NVM + cert) and an AES DMA in-place aliasing guard test.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
wolfhsm/wh_server.h Documents that DMA callbacks may run while the server NVM lock is held.
wolfhsm/wh_client.h Documents the “write all bytes (data + zero tail), or untouched if refused” destination-buffer contract for DMA reads.
src/wh_server_cert.c Implements deny-before-map, bounds cert_len, zero-fills mapped destination, and moves WRITE_POST outside the NVM lock for READTRUSTED_DMA.
src/wh_server_nvm.c Implements deny-before-map and zero-fills mapped destination for NVM READDMA.
test-refactor/wh_test_list.c Registers the new server DMA zero-fill test.
test-refactor/server/wh_test_dma_zerofill.c New regression test suite covering refusal paths, short reads, carry-over, oversized lengths, and null mapping/address cases.
test-refactor/client-server/wh_test_crypto_aes.c Adds AES DMA in-place aliasing test to guard against centralizing zero-fill in generic DMA address processing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/wh_server_nvm.c Outdated

@wolfSSL-Fenrir-bot wolfSSL-Fenrir-bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fenrir Automated Review — PR #486

Scan targets checked: wolfhsm-core-bugs, wolfhsm-crypto-bugs, wolfhsm-src

No new issues found in the changed files. ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants