Harden SSH parsing and add notice tooling
- Enforce exact service and channel names with bounded failure parsing - Add hash-pinned offline notice assembly and regression coverage - Record advisory dispositions, provenance, integration evidence, and remaining gates
This commit is contained in:
@@ -131,8 +131,9 @@ TLS_POLICY = """ /* mbedTLS retains this pointer: it must outlive every serve
|
||||
# the input object. Keep original upstream notices verbatim, rather than changing
|
||||
# their copyright year; the central project modification notice is separate.
|
||||
# Bounded server parser subset of official wolfSSL/wolfssh PRs 892, 881,
|
||||
# and 880 (reviewed alongside PR 899). Keep the 1.4.20 state machine and
|
||||
# password/async edits below. GetSize already uses safe remaining lengths.
|
||||
# and 880, plus the current-server PR899/902 disposition documented in
|
||||
# docs/ssh_parser_remaining_review.md. Preserve ordering/password/async edits.
|
||||
# GetSize already uses safe remaining lengths.
|
||||
WOLFSSH_PARSER_EDITS = (
|
||||
Edit("""int GetString(char* s, word32* sSz, const byte* buf, word32 len, word32 *idx)
|
||||
{
|
||||
@@ -200,9 +201,36 @@ WOLFSSH_PARSER_EDITS = (
|
||||
ret = GetString(serviceName, &nameSz, buf, len, &begin);
|
||||
if (ret != WS_SUCCESS)
|
||||
return ret;
|
||||
/* PR902 current-server subset: reject before publishing the transition.
|
||||
* The owner closes on this error; no best-effort disconnect is queued. */
|
||||
if (nameSz != sizeof("ssh-userauth") - 1 ||
|
||||
WMEMCMP(serviceName, "ssh-userauth", sizeof("ssh-userauth") - 1) != 0)
|
||||
return WS_INVALID_STATE_E;
|
||||
*idx = begin;
|
||||
|
||||
WLOG(WS_LOG_DEBUG, "Requesting service: %s", serviceName);"""),
|
||||
# PR899 fixes the reversed length predicate. The pinned handler additionally
|
||||
# needs a bounded recipient parser, not merely the later-tree one-line fix.
|
||||
Edit(""" if (ssh == NULL || buf == NULL || len != 0 || idx == NULL)
|
||||
ret = WS_BAD_ARGUMENT;
|
||||
|
||||
if (ret == WS_SUCCESS)
|
||||
ret = WS_CHANOPEN_FAILED;""", """ word32 begin, channelId;
|
||||
|
||||
if (ssh == NULL || buf == NULL || idx == NULL)
|
||||
return WS_BAD_ARGUMENT;
|
||||
|
||||
begin = *idx;
|
||||
ret = GetUint32(&channelId, buf, len, &begin);
|
||||
if (ret != WS_SUCCESS)
|
||||
return ret;
|
||||
if (begin != len)
|
||||
return WS_BUFFER_E;
|
||||
if (ChannelFind(ssh, channelId, WS_CHANNEL_ID_SELF) == NULL)
|
||||
return WS_INVALID_CHANID;
|
||||
|
||||
*idx = begin;
|
||||
ret = WS_CHANOPEN_FAILED;"""),
|
||||
Edit(""" channel->peerWindowSz += bytesToAdd;
|
||||
|
||||
WLOG(WS_LOG_INFO, " update peerWindowSz = %u",
|
||||
@@ -351,6 +379,17 @@ WOLFSSH_PARSER_EDITS = (
|
||||
ret = wc_ed25519_verify_msg_init(pk->signature + i, sz,"""),
|
||||
)
|
||||
|
||||
# DoChannelRequest's bounded GetString may truncate at 31 bytes; all recognized
|
||||
# names are shorter. Exact length first prevents short-name reads and aliases;
|
||||
# memcmp (not strncmp) also rejects embedded NULs. Keep branch bodies unchanged.
|
||||
WOLFSSH_PARSER_EDITS += tuple(
|
||||
Edit(f'WSTRNCMP(type, "{name}", typeSz) == 0',
|
||||
f'typeSz == sizeof("{name}") - 1 &&\n'
|
||||
f' WMEMCMP(type, "{name}", sizeof("{name}") - 1) == 0')
|
||||
for name in ("env", "shell", "exec", "subsystem", "pty-req", "window-change",
|
||||
"exit-status", "exit-signal", "auth-agent-req@openssh.com")
|
||||
)
|
||||
|
||||
ENTRIES = (
|
||||
Entry("dhcpserver", "lwip", "idf",
|
||||
"components/lwip/apps/dhcpserver/dhcpserver.c",
|
||||
@@ -649,6 +688,12 @@ def render_entry(entry: Entry, roots: dict[str, Path]) -> tuple[Path, bytes]:
|
||||
" * plus project restricted no-EXT_INFO correction. Provenance and\n"
|
||||
" * limitations: tools/wolfssh_order/README.md and delta.json.\n"
|
||||
" */\n")
|
||||
if entry.name == "wolfssh_internal":
|
||||
notice += ("/* Server parser review modified 2026-09-16: bounded CHANNEL_FAILURE\n"
|
||||
" * and ssh-userauth service validation; PR899/902 subset, not full PRs.\n"
|
||||
" * Local follow-up: exact bounded channel-request names.\n"
|
||||
" * Provenance/limits: docs/ssh_parser_remaining_review.md.\n"
|
||||
" */\n")
|
||||
if entry.header:
|
||||
notice += ("#if defined(_WOLFSSH_INTERNAL_H_) && \\\n"
|
||||
" (!defined(SAK_WOLFSSH_ORDER_ABI) || SAK_WOLFSSH_ORDER_ABI != 20260916)\n"
|
||||
|
||||
Reference in New Issue
Block a user