wolfsftp: report a failed remote write from SFTP put - #1182
wolfsftp: report a failed remote write from SFTP put#1182yosuke-wolfssl wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes a client-side SFTP upload correctness bug where wolfSSH_SFTP_Put() could incorrectly return success after a non-retryable remote write failure (e.g., server returns FXP_STATUS != FX_OK), and adds a regression test to ensure the failure is surfaced to callers via WS_FATAL_ERROR and ssh->error.
Changes:
- Update
STATE_PUT_WRITEinwolfSSH_SFTP_Put()to preserve the first non-retryable write error, avoid the remote close that could maskret, and unwind via local close + cleanup while returningWS_FATAL_ERROR. - Add a unit test that simulates an
FXP_HANDLEreply followed by anFXP_STATUSfailure on the first write, assertingwolfSSH_SFTP_Put()returnsWS_FATAL_ERRORandwolfSSH_get_error()reportsWS_SFTP_STATUS_NOT_OK.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| tests/unit.c | Adds a regression unit test that simulates a server write-status failure during SFTP put and asserts correct error propagation and cleanup. |
| src/wolfsftp.c | Ensures non-retryable write failures in SFTP put are recorded and returned, preventing later close logic from overwriting the failure. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #1182
Scan targets checked: wolfssh-bugs, wolfssh-src
Findings: 5
5 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Findings are non-blocking.
- STATE_PUT_WRITE logs, sets ret to WS_FATAL_ERROR, clears state->handleSz and moves to STATE_PUT_CLOSE_LOCAL when wolfSSH_SFTP_SendWritePacket() returns a non-positive size and NoticeError() is false. - ssh->error takes that return value, or WS_FATAL_ERROR for a size of zero, when ssh->error is still WS_SUCCESS. - The write loop is followed by a continue when ret is not WS_SUCCESS. - tests/unit.c gains WOLFSSH_TEST_SFTP_PUT, the SftpBuildReply() helper, and test_SftpClientPutWriteStatusFail(), which drives wolfSSH_SFTP_Put() over a staged handle reply and a write answered by an FXP_STATUS failure. Issue: F-10543
9f45e8e to
7010eb2
Compare
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
Fenrir Automated Review — PR #1182
Scan targets checked: wolfssh-bugs, wolfssh-src
Findings: 4
4 finding(s) posted as inline comments (see file-level comments below)
This review was generated automatically by Fenrir. Findings are non-blocking.
Problem
wolfSSH_SFTP_Put()reports a successful upload after the server rejects a write. WhenwolfSSH_SFTP_SendWritePacket()returns a non-positive size for a non-retryable reason — chiefly a serverFXP_STATUS != FX_OK, which surfaces asWS_SFTP_STATUS_NOT_OK— the code only consultedNoticeError()and dropped the error. Thedo/while (sz > 0)loop then ended normally, andSTATE_PUT_CLOSE_REMOTEoverwroteretwith the successful close result, soSTATE_PUT_CLEANUPreturnedWS_SUCCESS.Trigger: open a remote file successfully, then have the server fail the write because its filesystem is full or read-only. The application is told the transfer succeeded while the remote file is truncated or empty. Closes f-10543.
Fix (
src/wolfsftp.c)STATE_PUT_WRITEnow records the failure and routes around the close that would mask it:ssh->erroris filled in only when unset, so a specific code such asWS_SFTP_BAD_HEADERsurvives; the return staysWS_FATAL_ERRORper convention.state->handleSz = 0makesSTATE_PUT_CLOSE_REMOTEskip the close, the same mechanism theSTATE_PUT_OPEN_REMOTEfailure path already uses.continueafter the loop reaches cleanup withretintact.This mirrors
wolfSSH_SFTP_Get(), which likewise skips its remote close on a hard read failure. The trade-off is deliberate: the server-side handle stays open until session teardown, and a localretcannot survive aWS_WANT_READfrom the close, since it is re-initialised on every entry.Tests
test_SftpClientPutWriteStatusFail()reuses the existing in-memory client harness (SftpClientNewSession(),wolfSSH_TestChannelPutData()) to stage anFXP_HANDLEopen reply and anFXP_STATUSfailure for the only write, then assertsWS_FATAL_ERROR,WS_SFTP_STATUS_NOT_OK, and thatputStatewas freed.Verification
make check: 11 passed, 1 skipped, 0 failed.wolfsftp.cchange reverted.-Werror, lint plus 6 configs clean.