Skip to content

fix: harden peer-supplied atoi parsing#1095

Open
MarkAtwood wants to merge 1 commit into
wolfSSL:masterfrom
MarkAtwood:fix/wolfssh-atoi_peer_data
Open

fix: harden peer-supplied atoi parsing#1095
MarkAtwood wants to merge 1 commit into
wolfSSL:masterfrom
MarkAtwood:fix/wolfssh-atoi_peer_data

Conversation

@MarkAtwood

Copy link
Copy Markdown
Contributor

Replaces atoi() on peer-controlled numeric fields with bounded, error-reporting parsers. atoi() has undefined behavior on overflow (C99 7.20.1) and cannot signal malformed input.

  • #2881 — src/wolfscp.c: Add ScpParseUInt64 helper and replace the 3 atoi call sites parsing the SCP header file size (word32), mtime, and atime (word64). The helper validates every character is a digit, rejects empty input, and rejects values that overflow the field max, returning WS_SCP_BAD_MSG_E. Prevents a malicious peer from injecting garbage/overflowing sizes and timestamps.
  • #2882 — src/wolfterm.c: Add parseArg helper using strtol and replace the 2 atoi call sites parsing VT100 console parameters. Clamps invalid or out-of-range params (outside 0..65535) to 0, blocking a peer-supplied -1 from wrapping to 0xFFFFFFFF. This code is inside the existing USE_WINDOWS_API block.

Build-verified: ./autogen.sh && ./configure --with-wolfssl=... --enable-all && make -j8 completes clean (exit 0) with both fixes applied; wolfscp.c compiled and ran through the build. The wolfterm.c change is compiled only under USE_WINDOWS_API, so it was source-analyzed on the Linux build.

Reported by Fenrir static analysis.

Copilot AI review requested due to automatic review settings July 10, 2026 00:28

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 hardens parsing of peer-controlled numeric fields by removing atoi() usage and replacing it with bounded, error-reporting parsing helpers to prevent overflow UB and malformed-input acceptance in SCP and Windows console/VT100 handling.

Changes:

  • src/wolfscp.c: Introduces ScpParseUInt64() and replaces SCP header numeric parsing for file size and timestamps.
  • src/wolfterm.c: Introduces parseArg() (strtol-based) and replaces atoi() when parsing CSI/VT100 parameter arguments.

Reviewed changes

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

File Description
src/wolfterm.c Replaces atoi() with a bounded strtol-based helper for VT100/CSI argument parsing under USE_WINDOWS_API.
src/wolfscp.c Adds a digit-validating, overflow-checked unsigned parser and uses it for SCP size/mtime/atime parsing.

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

Comment thread src/wolfterm.c Outdated
Comment thread src/wolfscp.c Outdated
Comment thread src/wolfscp.c Outdated
Comment thread src/wolfscp.c Outdated

@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: COMMENT
Findings: 3 total — 3 posted, 0 skipped

Posted findings

  • [Medium] VT100 parser still accepts trailing junk after digitssrc/wolfterm.c:326-330
  • [Medium] SCP numeric parser lacks regression tests for malformed and overflow fieldssrc/wolfscp.c:1075-1131
  • [Medium] VT100 argument bounds behavior lacks targeted Windows testssrc/wolfterm.c:323-360

Review generated by Skoll.

Comment thread src/wolfterm.c
Comment thread src/wolfscp.c Outdated
Comment thread src/wolfterm.c
Replace atoi() and strtoull() on peer-controlled numeric fields with
bounded, error-reporting parsers. atoi() has undefined behavior on
overflow and cannot signal malformed input. strtoull() is C99, so it is
unavailable on some ports, and it accepts a leading sign and leading
whitespace that the SCP header does not permit.

- #2881 src/wolfscp.c: add ScpParseUInt64 helper; parse SCP header
  file size / mtime / atime with digit validation and overflow
  rejection against a caller-supplied max, replacing the 3 strtoull
  call sites from de23a69. Also rejects "+1", " 1" and "\t1" on all
  three fields, and "-1" on the unbounded scpMTime and scpATime, which
  had taken the wrapped 0xFFFFFFFFFFFFFFFF. The helper takes the field
  length, dropping the temporary '\n' written over the separating space
  at each call site, and with it the <stdint.h> include de23a69 had
  added for UINT32_MAX.
- #2882 src/wolfterm.c: add parseArg helper using strtol; clamp
  invalid/out-of-range VT100 params to 0, replacing 2 atoi call
  sites (blocks peer "-1" wrapping to 0xFFFFFFFF). A param with bytes
  left over after its digits, such as "12x", clamps to 0 rather than
  parsing as a short value. strtol is C89 and needs no replacement.
  Inside USE_WINDOWS_API, so not built on Linux or macOS. Also drop
  the unused maxIdx from getArgs().

Extend test_ScpGetFileSize and test_ScpGetTimestamp in tests/unit.c for
the fields the new parser rejects but strtoull() accepted: a signed or
whitespace-padded field, an empty field, a field holding a NUL, and the
64-bit maximum and one past it on the timestamps. Drop the strtoull()
and ERANGE references from those test comments.

Issue: F-2881, F-2882
@ejohnstown
ejohnstown force-pushed the fix/wolfssh-atoi_peer_data branch from 5405bcb to 46a4988 Compare July 24, 2026 23:52
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