F-8824: enable config files without trailing newline - #1156
Conversation
81fef31 to
601d645
Compare
There was a problem hiding this comment.
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.
| /* Ensure trailing null so buffer is a string, even without a newline */ | ||
| in = (byte*)WMALLOC(inSz + 1, NULL, 0); |
| savedStdin = dup(STDIN_FILENO); | ||
| devNull = open("/dev/null", O_RDONLY); | ||
| if (devNull >= 0) { | ||
| dup2(devNull, STDIN_FILENO); | ||
| } |
wolfSSL-Fenrir-bot
left a comment
There was a problem hiding this comment.
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.
|
|
||
| /* 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); |
There was a problem hiding this comment.
🔵 [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.
| WriteKnownHosts(hostsPath, contents); | ||
|
|
||
| printf(" known_hosts with %s.\n", cases[i].label); | ||
| AssertIntEQ(ClientPublicKeyCheck(pubKey, (word32)sizeof(pubKey), |
There was a problem hiding this comment.
🔵 [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.
| WriteKnownHosts(hostsPath, contents); | ||
|
|
||
| printf(" known_hosts with %s.\n", cases[i].label); | ||
| AssertIntEQ(ClientPublicKeyCheck(pubKey, (word32)sizeof(pubKey), |
There was a problem hiding this comment.
🔵 [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.
|
|
||
| /* 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); |
There was a problem hiding this comment.
🔵 [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.
| /* 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); |
There was a problem hiding this comment.
⚪ [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.
No description provided.