Skip to content

wolfterm: bound escBuf saves and clear esc state on OSC resume#1076

Merged
ejohnstown merged 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_5903
Jul 21, 2026
Merged

wolfterm: bound escBuf saves and clear esc state on OSC resume#1076
ejohnstown merged 1 commit into
wolfSSL:masterfrom
yosuke-wolfssl:fix/f_5903

Conversation

@yosuke-wolfssl

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

Copy link
Copy Markdown
Contributor

Overview

Hardens the escBuf partial-sequence reassembly in wolfSSH_DoControlSeq and
fixes an escape-state leak in the wolfSSH_ConvertConsole OSC resume path
(src/wolfterm.c). Windows-only console handling (USE_WINDOWS_API).

Changes

  1. Tighten both escBuf save branches. When a CSI sequence's arguments run
    to the end of a buffer with no command char, the partial bytes are stashed in
    ssh->escBuf for the next call. escBuf is WOLFSSL_MAX_ESCBUF bytes, so a
    save of exactly that length fills it with no room for continued state. Both
    save branches now reject bufSz - *idx >= WOLFSSL_MAX_ESCBUF before the
    WMEMCPY and log via WLOG(WS_LOG_ERROR, ...), matching the boundary
    semantics of the resume check and keeping the two branches consistent.

  2. Guard the initial-parse CSI save branch. The initial-parse path
    (escState was WC_ESC_NONE, buffer opens with ESC [) copied into escBuf
    with no capacity bound. In the default build getArgs caps the advance at
    WOLFSSH_MAX_CONSOLE_ARGS (16) < WOLFSSL_MAX_ESCBUF (19), so the copy was
    already safe; the guard is defense-in-depth for a custom
    WOLFSSH_MAX_CONSOLE_ARGS > WOLFSSL_MAX_ESCBUF build.

  3. Clear escape state on OSC resume completion. When a split OSC sequence
    completes via the resume handler in wolfSSH_ConvertConsole, reset
    escState = WC_ESC_NONE (not just escBufSz). Without this, escState
    stayed WS_ESC_OSC and the next call re-entered OSC parsing on plain bytes
    instead of printing them.

Testing

Extended test_wolfSSH_ConvertConsole in tests/api.c:

  • Split CSI across calls (ESC [ | 12 | m) — the continuation carries
    only argument bytes; verifies reassembly waits (WS_WANT_READ) and then
    completes (WS_SUCCESS) without reading past the buffer.
  • Trailing plain byte after completion — a plain argument byte after the
    sequence finishes must be printed (WS_SUCCESS), not swallowed back into a
    new parse.
  • Single-buffer args-to-end (ESC [ 1 2) — args run to the end of one
    buffer; verifies the partial save waits and completes on the next byte.

Verified on native Windows (Visual Studio Build Tools 2022, static Debug x64):

api-test EXITCODE=0

Local GCC preflight sweep (--enable-all, Zephyr defines, strncpy lint) clean.

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

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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

Scan targets checked: wolfssh-bugs, wolfssh-src

No new issues found in the changed files. ✅

@aidangarske aidangarske 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.

🐺 Skoll Code Review

Overall recommendation: REQUEST_CHANGES
Findings: 1 total — 1 posted, 0 skipped

Posted findings

  • [High] CSI capacity errors are swallowed on resumesrc/wolfterm.c:684-691

Review generated by Skoll.

Comment thread src/wolfterm.c
@aidangarske
aidangarske self-requested a review July 9, 2026 07:09
aidangarske
aidangarske previously approved these changes Jul 9, 2026

@aidangarske aidangarske 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.

over to @ejohnstown

Harden the partial-sequence reassembly in wolfSSH_DoControlSeq and fix an
escape-state leak in the wolfSSH_ConvertConsole OSC resume path
(USE_WINDOWS_API console handling).

- Tighten both escBuf partial-save branches to reject bufSz - *idx >=
  WOLFSSL_MAX_ESCBUF before the WMEMCPY and log via WLOG. escBuf is
  WOLFSSL_MAX_ESCBUF bytes, so a save of exactly that length fills it with
  no room for later state; rejecting the boundary keeps the two branches
  consistent and matches the resume check.

- Add the capacity guard to the initial-parse CSI save branch, which
  previously copied into escBuf with no bound. In the default build getArgs
  caps the advance below WOLFSSL_MAX_ESCBUF so the copy was already safe;
  the guard prevents a custom WOLFSSH_MAX_CONSOLE_ARGS > WOLFSSL_MAX_ESCBUF
  build from overflowing escBuf.

- Clear escState to WC_ESC_NONE when a resumed OSC sequence completes, not
  just escBufSz. Without this escState stayed WS_ESC_OSC and the next call
  re-entered OSC parsing on plain bytes instead of printing them.

Extend test_wolfSSH_ConvertConsole with a CSI sequence split across three
calls (ESC[ | args | command char), a trailing plain byte that must be
printed once state is cleared, and a single buffer whose CSI args run to
the end and complete on the next byte.
@yosuke-wolfssl yosuke-wolfssl changed the title Bound CSI continuation parse and clear esc state on completion wolfterm: bound escBuf saves and clear esc state on OSC resume Jul 21, 2026
@ejohnstown
ejohnstown merged commit 0b819b0 into wolfSSL:master Jul 21, 2026
142 checks passed
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.

6 participants