wolfssh/scp: complete rekey that starts mid-transfer#1018
wolfssh/scp: complete rekey that starts mid-transfer#1018yosuke-wolfssl wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes a hang that can occur when an SSH rekey is triggered mid-SCP transfer, leaving the SCP state machine stuck in WS_REKEYING / window-full conditions. It does so by adding SCP send/read helpers that actively flush pending output and drive wolfSSH_worker() through rekey/window-full states, plus an API test matrix that forces rekeys during transfers.
Changes:
- Add
ScpStreamSend/ScpStreamReadhelpers insrc/wolfscp.cto flush queued output and progress rekey/window-full conditions without busy-spinning in non-blocking mode. - Update SCP message/file paths to use the new helpers, and adjust
ReceiveScpMessageto consume already-buffered channel data during rekey completion. - Add
scp_rekey_test()and four SCP rekey test cases (blocking/non-blocking × toServer/fromServer) intests/api.c.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/wolfscp.c |
Introduces rekey/window-full-aware stream send/read helpers and uses them across SCP control/data paths. |
tests/api.c |
Adds a forced mid-transfer rekey regression test harness and registers four SCP rekey test variants. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
c7353e8 to
e332767
Compare
e332767 to
18143af
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #1018
Scan targets checked: wolfssh-bugs, wolfssh-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.
Summary
An SSH rekey triggered partway through an SCP transfer (for example by a low
highwater threshold) could leave the transfer stuck in a
WS_REKEYINGorwindow-full state and hang the client. This adds send/read helpers that carry
the transfer through a mid-transfer rekey, plus a test matrix that forces one.
Changes
src/wolfscp.cScpStreamSend(new): flushes queued output so a KEXINIT enqueued by aprior send is transmitted, then drives
wolfSSH_workerwhile the connectionis keying or the channel window is full. Returns a non-blocking
WS_WANT_READ/WS_WANT_WRITEwant instead of spinning.ScpStreamRead(new): read-side counterpart. Flushes pending output,retries the read across a mid-read rekey, and stays error-code transparent so
each caller keeps its existing branch handling.
ReceiveScpMessage: reads already-buffered channel data directly insteadof blocking on the socket when a control message arrives while a rekey is
completing.
tests/api.cscp_rekey_test(nonBlock, toServer)harness: connects an SCP client, setsa low highwater (256 B) so a rekey fires mid-transfer of a 2 KB payload, runs
the transfer, and verifies the received file matches the source.
test_wolfSSH_SCP_ReKey,_NonBlock,_ToServer,_ToServer_NonBlock.Non-blocking variants are bounded by
SCP_REKEY_MAX_TRIESso a regressionfails the assertion instead of hanging CI.
Verification
Built
--enable-allunder ASan+UBSan and rantests/api.test: all assertionspass, 29 mid-transfer rekeys exercised, no sanitizer reports attributable to the
change.