Skip to content

Stop the client discarding the remote command - #1162

Merged
JacobBarthelmeh merged 1 commit into
wolfSSL:masterfrom
ejohnstown:clifix
Aug 12, 2026
Merged

Stop the client discarding the remote command#1162
JacobBarthelmeh merged 1 commit into
wolfSSL:masterfrom
ejohnstown:clifix

Conversation

@ejohnstown

Copy link
Copy Markdown
Contributor

wolfssh host command always opened an interactive shell and ran nothing. keepOpen was hardcoded to 1, so the TERMINAL channel type was set right after EXEC, freeing the command and reverting to a shell.

Derive keepOpen from whether a command was given, and gate the raw mode switch the same way, since a remote command runs with no pty. Also removes -N, which was parsed and never read.

Issue: F-8816

@ejohnstown
ejohnstown requested review from wolfSSL-Fenrir-bot and a lite review from Copilot August 12, 2026 18:03
@ejohnstown ejohnstown self-assigned this Aug 12, 2026

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

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Fixes wolfssh host command incorrectly opening an interactive shell by deriving “keep terminal open” behavior from whether a remote command is provided, and updates CLI/docs accordingly.

Changes:

  • Remove the unused -N option from parsing and documentation.
  • Set keepOpen based on whether a command was provided to avoid discarding EXEC.
  • Gate terminal raw-mode switching to interactive sessions only.

Reviewed changes

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

File Description
apps/wolfssh/wolfssh.c Removes -N, derives keepOpen from presence of command, and gates raw terminal mode.
apps/wolfssh/README.md Removes -N docs and clarifies destination vs. command behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread apps/wolfssh/wolfssh.c
Comment thread apps/wolfssh/wolfssh.c Outdated

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

Scan targets checked: wolfssh-bugs, wolfssh-src
Findings: 2

Low (1)

Remote command of 4096+ bytes is silently dropped, producing a malformed exec request

File: apps/wolfssh/wolfssh.c:1062
Function: wolfSSH_Client
Category: SSH protocol violations

wolfSSH_SetChannelType returns WS_SUCCESS while discarding names with nameSz >= WOLFSSH_MAX_CHN_NAMESZ (src/ssh.c:1677-1700), leaving ssh->channelName NULL. With keepOpen now 0, SendChannelRequest emits an exec request with no command string (internal.c:20400), so the user's command is silently never sent. Adjacent to known finding #8816, which masked this path by always overwriting the exec command with a shell request.

Recommendation: Reject commands whose length is >= WOLFSSH_MAX_CHN_NAMESZ in config_parse_command_line with an explicit error before connecting.

Referenced code: apps/wolfssh/wolfssh.c:1062-1066 (5 lines)


Info (1)

I/O thread guard is now a tautology after keepOpen is derived from config.command

File: apps/wolfssh/wolfssh.c:1093
Function: wolfSSH_Client
Category: Dead/unreachable code

keepOpen is now defined as config.command == NULL (line 973), so config.command != NULL || keepOpen == 1 is true for every input. The guard reads as a two-mode selector but can never be false, which is misleading now that keepOpen carries meaning.

Recommendation: Drop the condition and run the thread block unconditionally, or replace it with a check that reflects an actually reachable false case.


This review was generated automatically by Fenrir. Findings are non-blocking.

- keepOpen was hardcoded to 1, so the TERMINAL channel type was always
  set right after EXEC, freeing the command and reverting to a shell.
- Derive keepOpen from whether a command was given.
- Gate MODES_CLEAR() the same way. A remote command runs with no pty,
  so its LF terminated output needs OPOST left on.
- The SINGLE_THREADED guard is now unconditional, matching what it did
  when keepOpen was always 1.
- Remove -N. It was parsed into config.noCommand and read nowhere, and
  making it work needs a way to request no session at all.
- Add the optional command to the usage line.
- Reject a command of WOLFSSH_MAX_CHN_NAMESZ or longer. SetChannelType
  discards it and still returns WS_SUCCESS, so the client would send an
  exec request with no command string at all.
- Drop the I/O thread guard. With keepOpen derived from config.command,
  the condition was true for every input.

Issue: F-8816
@ejohnstown

Copy link
Copy Markdown
Contributor Author

Fenrir Automated Review — PR #1162

Scan targets checked: wolfssh-bugs, wolfssh-src Findings: 2

Low (1)

Remote command of 4096+ bytes is silently dropped, producing a malformed exec request

File: apps/wolfssh/wolfssh.c:1062 Function: wolfSSH_Client Category: SSH protocol violations

wolfSSH_SetChannelType returns WS_SUCCESS while discarding names with nameSz >= WOLFSSH_MAX_CHN_NAMESZ (src/ssh.c:1677-1700), leaving ssh->channelName NULL. With keepOpen now 0, SendChannelRequest emits an exec request with no command string (internal.c:20400), so the user's command is silently never sent. Adjacent to known finding #8816, which masked this path by always overwriting the exec command with a shell request.

Recommendation: Reject commands whose length is >= WOLFSSH_MAX_CHN_NAMESZ in config_parse_command_line with an explicit error before connecting.

Referenced code: apps/wolfssh/wolfssh.c:1062-1066 (5 lines)

Info (1)

I/O thread guard is now a tautology after keepOpen is derived from config.command

File: apps/wolfssh/wolfssh.c:1093 Function: wolfSSH_Client Category: Dead/unreachable code

keepOpen is now defined as config.command == NULL (line 973), so config.command != NULL || keepOpen == 1 is true for every input. The guard reads as a two-mode selector but can never be false, which is misleading now that keepOpen carries meaning.

Recommendation: Drop the condition and run the thread block unconditionally, or replace it with a check that reflects an actually reachable false case.

This review was generated automatically by Fenrir. Findings are non-blocking.

Fixed the command length issue, and updated the tautological check.

@ejohnstown ejohnstown assigned wolfSSL-Bot and unassigned ejohnstown Aug 12, 2026
@JacobBarthelmeh
JacobBarthelmeh merged commit 31ed01d into wolfSSL:master Aug 12, 2026
154 checks passed
@ejohnstown
ejohnstown deleted the clifix branch August 12, 2026 20:40
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.

5 participants