Skip to content

Zeroize SFTP file payload buffers before freeing#1053

Open
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_5582
Open

Zeroize SFTP file payload buffers before freeing#1053
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_5582

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Zeroize SFTP file payload buffers before freeing

Summary

The shared SFTP receive/send buffer can hold transferred file contents, but it
was released with WFREE only. Freed heap could retain SFTP file data until
allocator reuse, exposing sensitive file contents to local memory disclosure or
forensic tooling.

This PR zeroizes SFTP buffers that may carry file payload before they are freed
or trimmed, and adds a build gate so deployments can opt out for bulk-transfer
throughput.

Changes

Zeroization

  • wolfSSH_SFTP_buffer_free()ForceZero(buffer->data, buffer->sz) before
    WFREE. Covers the read-response path and every per-state buffer release that
    funnels through this helper.
  • wolfSSH_SFTP_RecvSetSend()ForceZero before the WFREE, kept inside
    the existing buf != state->buffer.data aliasing guard so the outgoing
    response buffer (when it aliases the request buffer) is never wiped.
  • wolfSSH_SFTP_buffer_set_size() — wipe the trimmed-off region
    (ForceZero(buffer->data + sz, buffer->sz - sz)) before shrinking. This helper
    reduces a buffer's logical length without reallocating, so without this a
    shrink could strand file payload past the new size. Pairing the shrink-time
    wipe with the free-time wipe gives a clean invariant: every sensitive byte is
    cleared either when it is trimmed off or when the buffer is freed.

ForceZero is already declared in wolfssh/misc.h (included by wolfsftp.c);
no new include is needed. All three functions are static — no public API or
signature change.

Build gate

New WOLFSSH_NO_SFTP_BUFFER_ZERO macro gates the three zeroization sites,
secure-by-default (zeroization enabled unless explicitly disabled). The wipe of
bulk read/write response buffers is a measurable per-chunk cost on large
transfers, so deployments that prioritize throughput over this defense-in-depth
can opt out.

  • configure.ac--disable-sftp-zeroize (default enabled), emits
    -DWOLFSSH_NO_SFTP_BUFFER_ZERO when disabled, plus a config-summary line.
  • The three sites use direct #ifndef guards (no wrapper macro) so ForceZero
    stays visible for security auditing.

CI

  • .github/workflows/os-check.yml — added --enable-sftp --disable-sftp-zeroize
    to the build matrix so the disabled code path is compiled and make check-ed
    on ubuntu/macos across the wolfSSL version matrix. The default (zeroize-on)
    path is already covered by the existing --enable-sftp / --enable-all
    entries.

Scope notes

This wipes buffers that actually carry file payload. It intentionally does not
wipe never-written uninitialized slack (e.g. the tail of a short-read server
response buffer), which never held this request's file data and is outside the
finding's scope. The client read path reads file data into the caller-provided
out buffer, not a wolfSSH-owned buffer, so there is nothing for wolfSSH to
wipe there.

Testing

  • ./configure --enable-sftp && make && make check — 7/7 pass.
  • ./configure --enable-sftp --disable-sftp-zeroize && make && make check
    7/7 pass (disabled path builds and runs).

@yosuke-wolfssl yosuke-wolfssl self-assigned this Jun 23, 2026
Copilot AI review requested due to automatic review settings June 23, 2026 05:51

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 aims to harden SFTP data handling by wiping (zeroizing) heap buffers that may contain transferred file contents before they are freed, reducing the risk of sensitive data remaining recoverable from heap memory after WFREE().

Changes:

  • Update wolfSSH_SFTP_buffer_free() to call ForceZero() before freeing buffer->data.
  • Update wolfSSH_SFTP_RecvSetSend() to call ForceZero() before freeing the previous state->buffer.data allocation (when it’s a distinct allocation).

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

Comment thread src/wolfsftp.c
Comment thread src/wolfsftp.c

@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 #1053

Scan targets checked: wolfssh-bugs, wolfssh-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