Skip to content

Append injected data at the end of the input buffer - #11044

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

Append injected data at the end of the input buffer#11044
yosuke-wolfssl wants to merge 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_7521

Conversation

@yosuke-wolfssl

@yosuke-wolfssl yosuke-wolfssl commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Problem

Two defects, both reached by feeding one TLS record to wolfSSL_inject() over
several calls.

1. wolfSSL_inject() appended at the wrong offset (src/ssl_api_rw.c).
New bytes belong after data already buffered but not yet consumed, at
inputBuffer.buffer + length; the copy went to inputBuffer.buffer + idx, the
start of the unconsumed region. When the buffer is drained (idx == length)
the two coincide, which is why existing coverage never caught it. Otherwise the
new bytes overwrote a retained partial record and length then claimed the
stale trailing bytes as valid, so a record fed in over several calls never
reassembled. The free-space check compounded this, measuring
bufferSize - usedLength (space for an append at length) while writing at
idx. Closes f-7521.

2. GrowInputBuffer() destroys retained data when the allocator aliases
(src/internal.c).
XMALLOC(DYNAMIC_TYPE_IN_BUFFER) returns the buffer
already in use under HAVE_IO_POOL (a single static pool_in) and under static
memory with WOLFMEM_IO_POOL_FIXED (hint->inBuf). GrowInputBuffer() copies
the retained bytes to the front, then immediately zeroes that same memory:

XMEMCPY(tmp, buffer + idx, usedLength);  /* tmp == buffer */
if (ssl->buffers.inputBuffer.dynamicFlag && IsEncryptionOn(ssl, 1))
    ForceZero(buffer, length);           /* wipes what was just copied */

A WOLFSSL_STATIC_MEMORY-only guard existed, but it did not cover
HAVE_IO_POOL, and it never moved the data — so it also mis-read stale bytes
whenever idx > 0.

wolfSSL_inject() is the first caller able to reach this. It sizes the buffer
to the chunk it is handed, so a later grow still holds a partial record.
GetInputData_ex() always requests the whole record, so its one grow per record
lands at usedLength == 0, where there is nothing to preserve.

Fix (src/ssl_api_rw.c)

  • maxLength measures free space past inputBuffer.length.
  • XMEMCPY appends at inputBuffer.length.
  • BUFFER_ERROR when usedLength or maxLength is negative, mirroring
    GetInputData_ex().

Also documents the BUFFER_ERROR and APP_DATA_READY returns, which the source
comment and the EN/JA doxygen did not both list.

Fix (src/internal.c)

GrowInputBuffer() now detects tmp == inputBuffer.buffer for any allocator,
moves the retained bytes down with XMEMMOVE, and zeroes only the now-stale
remainder. This replaces the WOLFSSL_STATIC_MEMORY guard rather than adding a
parallel HAVE_IO_POOL copy: aliasing is a property of the allocator, and
XMALLOC_USER lets applications supply their own pooling allocator.

Tests

test_wolfSSL_inject_partial_record in tests/api.c:

Phase Injection pattern Path covered
1 one record in 7-byte chunks, wolfSSL_read() between each partial record retained
2 8 KB record split 3 bytes / remainder grow with a partial record retained

Verification

Config Result
--enable-iopool 444 passed, 0 failed
--enable-all 1770 passed, 0 failed
default 444 passed, 0 failed
--enable-staticmemory 446 passed, 0 failed
--enable-dtls --enable-dtls13 517 passed, 0 failed
--enable-iopool + ASan/UBSan 0 failed, sanitizer-clean

Negative controls: reverting src/ssl_api_rw.c fails the new test in a default
build; reverting src/internal.c fails it under --enable-iopool, the
configuration that was red on PRB. The WOLFSSL_STATIC_MEMORY half was
confirmed separately with a white-box probe over a WOLFMEM_IO_POOL_FIXED pool
(retained bytes mis-read when idx > 0 before the change, correct after); that
probe is not part of this PR.

The out-of-bounds write the bounds mismatch permits needs idx > 0 at inject
time, which requires --enable-readahead; without it ProcessReply() drains
every buffered record first. The corruption is reachable in a default build and
is what the test covers.

Copilot AI review requested due to automatic review settings August 4, 2026 02:23
@yosuke-wolfssl yosuke-wolfssl self-assigned this Aug 4, 2026

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

Fixes wolfSSL_inject() so injected transport bytes are appended after any already-buffered (but unconsumed) input data, preventing partial TLS records from being overwritten and ensuring multi-call injection reassembles correctly.

Changes:

  • Update wolfSSL_inject() to append at inputBuffer.length, compute free space relative to length, and return BUFFER_ERROR on inconsistent buffer state.
  • Document additional return codes in both source comments and generated doxygen headers (EN/JA).
  • Add a regression test that injects TLS records in multiple chunks, including a grow-with-partial-record path.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/ssl_api_rw.c Fixes injection append offset and strengthens buffer-length validation/error returns.
tests/api.c Adds regression coverage for partial-record injection (no-grow and grow paths).
doc/dox_comments/header_files/ssl.h Updates doxygen return-code documentation for wolfSSL_inject().
doc/dox_comments/header_files-ja/ssl.h Same doxygen documentation update for JA headers.
Suppressed comments (1)

tests/api.c:37392

  • Same capacity issue as above: recordSz is sourced from test_ctx.s_len and copied into record (allocated as TEST_INJECT_BIG_SZ + 512) without checking whether it fits. If the write is split into multiple records/chunks in some build configurations, this XMEMCPY() can overflow record. Ensure record is (re)allocated to at least recordSz before copying.

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

Comment thread tests/api.c
Comment thread doc/dox_comments/header_files/ssl.h Outdated
Comment thread doc/dox_comments/header_files-ja/ssl.h Outdated
@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

MemBrowse Memory Report

gcc-arm-cortex-m3

  • FLASH: .text +48 B (+0.0%, 122,991 B / 262,144 B, total: 47% used)

gcc-arm-cortex-m4

  • FLASH: .text +64 B (+0.0%, 201,173 B / 262,144 B, total: 77% used)

gcc-arm-cortex-m4-dtls13

  • FLASH: .text +64 B (+0.0%, 181,988 B / 1,048,576 B, total: 17% used)

gcc-arm-cortex-m4-openssl-compat

  • FLASH: .text +64 B (+0.0%, 772,908 B / 1,048,576 B, total: 74% used)

gcc-arm-cortex-m4-pq

  • FLASH: .text +64 B (+0.0%, 281,152 B / 1,048,576 B, total: 27% used)

gcc-arm-cortex-m4-tls13

  • FLASH: .text +64 B (+0.0%, 237,319 B / 262,144 B, total: 91% used)

gcc-arm-cortex-m7-pq

  • FLASH: .text +64 B (+0.0%, 281,728 B / 1,048,576 B, total: 27% used)

gcc-arm-cortex-m7-tls13

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

Scan targets checked: wolfcrypt-rs-bugs, wolfssl-bugs, wolfssl-src

Findings: 2
2 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread src/ssl_api_rw.c
Comment thread tests/api.c
Comment thread src/ssl_api_rw.c
Comment thread tests/api.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 #11044

Scan targets checked: wolfcrypt-rs-bugs, wolfssl-bugs, wolfssl-src

No new issues found in the changed files. ✅

@yosuke-wolfssl
yosuke-wolfssl force-pushed the fix/f_7521 branch 2 times, most recently from 0667ecc to 5367278 Compare August 5, 2026 00:24

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

Scan targets checked: wolfcrypt-rs-bugs, wolfssl-bugs, wolfssl-src

No new issues found in the changed files. ✅

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

Scan targets checked: wolfcrypt-rs-bugs, wolfssl-bugs, wolfssl-src

Findings: 1
1 finding(s) posted as inline comments (see file-level comments below)

This review was generated automatically by Fenrir. Findings are non-blocking.

Comment thread src/ssl_api_rw.c

@dgarske dgarske left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'd like either @SparkiDev or @julek-wolfssl to also review this before merge, but changes look good to me.

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.

5 participants