From 85f7978eb459e257834d8340f3b5be8631ba578f Mon Sep 17 00:00:00 2001 From: John Safranek Date: Fri, 4 Sep 2026 16:41:08 -0700 Subject: [PATCH] SCP: report only a read want from SCP_accept wolfSSH_SCP_accept() reported any want held in ssh->error in place of the DoScpRequest() result. A short send that SendChannelData() accepts leaves WS_WANT_WRITE there with nothing clearing it on a later flush, so a terminal result came back as retryable and the retry re-entered the state machine, re-sending an abort confirmation or reading past a bad message. - Substitute the want only when the result is WS_FATAL_ERROR and the want is WS_WANT_READ, the one case GetInputData() hides by value. - Leave write wants alone; the SCP state machine already returns them. --- src/wolfscp.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/wolfscp.c b/src/wolfscp.c index e5d95a3e..c247eacc 100644 --- a/src/wolfscp.c +++ b/src/wolfscp.c @@ -903,14 +903,11 @@ int wolfSSH_SCP_accept(WOLFSSH* ssh) * anything non-negative as done the way wolfSSH_accept() does. */ ret = WS_SCP_COMPLETE; } - else { - /* A non-blocking want on a read path surfaces as a generic error - * with the want recorded in ssh->error (see GetInputData), so - * report it as the want the caller is told to retry on. */ - int err = wolfSSH_get_error(ssh); - - if (err == WS_WANT_READ || err == WS_WANT_WRITE) - ret = err; + else if (ret == WS_FATAL_ERROR && wolfSSH_get_error(ssh) == WS_WANT_READ) { + /* GetInputData() hides a read want behind WS_FATAL_ERROR. Write + * wants come back by value, and a stale WS_WANT_WRITE from an + * accepted short send can outlive a terminal result. */ + ret = WS_WANT_READ; } return ret;