Skip to content

F-8824: enable config files without trailing newline - #1156

Open
padelsbach wants to merge 1 commit into
wolfSSL:masterfrom
padelsbach:config-file-no-newline
Open

F-8824: enable config files without trailing newline#1156
padelsbach wants to merge 1 commit into
wolfSSL:masterfrom
padelsbach:config-file-no-newline

Conversation

@padelsbach

Copy link
Copy Markdown
Contributor

No description provided.

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

Enables known_hosts parsing to handle files whose last line does not end with a trailing newline, and adds regression coverage to prevent reintroducing the issue.

Changes:

  • Make load_der_file() allocate an extra byte and NUL-terminate the buffer past the file contents.
  • Update ClientPublicKeyCheck() parsing to avoid clobbering the last byte and to normalize CRLF line endings.
  • Add a regression test that exercises last-entry matching with \n, no trailing newline, and \r\n.

Reviewed changes

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

File Description
apps/wolfssh/common.c NUL-terminate loaded file buffers and normalize CRLF in known_hosts parsing.
tests/regress.c Add regression test for known_hosts last-line handling (with/without trailing newline and CRLF).

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

Comment thread apps/wolfssh/common.c
Comment on lines +104 to +105
/* Ensure trailing null so buffer is a string, even without a newline */
in = (byte*)WMALLOC(inSz + 1, NULL, 0);
Comment thread tests/regress.c
Comment on lines +5875 to +5879
savedStdin = dup(STDIN_FILENO);
devNull = open("/dev/null", O_RDONLY);
if (devNull >= 0) {
dup2(devNull, STDIN_FILENO);
}

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

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.

Comment thread tests/regress.c

/* A regression falls through to the "add it to known hosts?" prompt, so
* point stdin at EOF: the test then fails rather than waiting forever. */
savedStdin = dup(STDIN_FILENO);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] Unchecked dup() leaves stdin permanently redirected to /dev/null · Incorrect error handling

dup(STDIN_FILENO) is used without checking for -1, while the paired open is guarded by if (devNull >= 0). On failure the restore dup2(savedStdin, STDIN_FILENO) silently fails and close(-1) is called, leaving fd 0 pointing at /dev/null for every later test in the suite.

Fix: Assert savedStdin >= 0 and guard the restoring dup2/close on that same condition.

Comment thread tests/regress.c
WriteKnownHosts(hostsPath, contents);

printf(" known_hosts with %s.\n", cases[i].label);
AssertIntEQ(ClientPublicKeyCheck(pubKey, (word32)sizeof(pubKey),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] New known_hosts test never exercises the mismatched-key rejection branch · Missing edge-case coverage on a function the PR also changed

All three cases assert ClientPublicKeyCheck(...) == 0 for a matching entry. The badMatch branch at common.c:470 — target host present with a different key, which must return -1 — is never exercised, so the PR's new CR-stripping of the key field is untested against over-permissive matching.

Fix: Add a case whose last line names targetName with a different base64 key and assert ClientPublicKeyCheck returns non-zero.

Comment thread tests/regress.c
WriteKnownHosts(hostsPath, contents);

printf(" known_hosts with %s.\n", cases[i].label);
AssertIntEQ(ClientPublicKeyCheck(pubKey, (word32)sizeof(pubKey),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] New known_hosts test asserts only acceptance, never rejection · Weak or missing assertions

All three cases assert only that ClientPublicKeyCheck returns 0 (host accepted). The badMatch branch at apps/wolfssh/common.c:470 — known host, wrong key — is never exercised, so a matcher that accepts any key passes this test.

Fix: Add a case whose last entry stores a different base64 key for targetName and assert ClientPublicKeyCheck returns non-zero.

Comment thread tests/regress.c

/* Plain mkdir/rmdir rather than WMKDIR/WRMDIR: those only exist in
* builds that compile the SCP or SFTP file system layer. */
AssertIntEQ(mkdir(homeDir, 0700), 0);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 [Low] PID-named fixture directory is not cleared before creation, aborting the whole suite · Race conditions in setup/teardown

homeDir is wolfssh_kh_\<pid>.tmp in the CWD and is only removed on the success path; an earlier aborted run leaves it behind, so mkdir returns EEXIST on PID reuse and the failed AssertIntEQ calls abort(), killing the entire regress binary.

Fix: Remove any stale fixture tree first, or tolerate EEXIST by accepting errno == EEXIST from mkdir.

Comment thread tests/regress.c
/* A regression falls through to the "add it to known hosts?" prompt, so
* point stdin at EOF: the test then fails rather than waiting forever. */
savedStdin = dup(STDIN_FILENO);
devNull = open("/dev/null", O_RDONLY);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚪ [Info] stdin redirection failure leaves the test able to block indefinitely · Hardcoded paths, ports, or environment dependencies

The /dev/null open and both dup/dup2 results are unchecked. If the redirection does not take effect, a parse regression reaches GetConfirmation()'s getchar() on the real stdin and the test hangs in CI instead of failing.

Fix: Assert that dup, open, and dup2 all succeed before running the loop.

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.

3 participants