[openssh-commits] [openssh] 05/15: OSS-Fuzz: Add fuzzer for parsing
git+noreply at mindrot.org
git+noreply at mindrot.org
Fri Oct 9 21:38:23 AEDT 2026
This is an automated email from the git hooks/post-receive script.
dtucker pushed a commit to branch master
in repository openssh.
commit 57fa7ed4172ed80d0d1d2cdbc05b408425d2a1d3
Author: Arthur Chan <arthur.chan at adalogics.com>
AuthorDate: Thu May 28 17:27:02 2026 +0100
OSS-Fuzz: Add fuzzer for parsing
Signed-off-by: Arthur Chan <arthur.chan at adalogics.com>
---
regress/misc/fuzz-harness/Makefile | 5 +-
regress/misc/fuzz-harness/misc_parse_fuzz.cc | 167 +++++++++++++++++++++++++++
2 files changed, 171 insertions(+), 1 deletion(-)
diff --git a/regress/misc/fuzz-harness/Makefile b/regress/misc/fuzz-harness/Makefile
index 97f95db24..d632b25c7 100644
--- a/regress/misc/fuzz-harness/Makefile
+++ b/regress/misc/fuzz-harness/Makefile
@@ -16,7 +16,7 @@ TARGETS=pubkey_fuzz sig_fuzz authopt_fuzz authkeys_fuzz sshsig_fuzz \
sshsigopt_fuzz privkey_fuzz kex_fuzz agent_fuzz \
mkcorpus_sntrup761 sntrup761_enc_fuzz sntrup761_dec_fuzz \
ssh_client_session_fuzz sftp_server_msg_fuzz authfd_reply_fuzz \
- sftp_client_fuzz
+ sftp_client_fuzz misc_parse_fuzz
all: $(TARGETS)
@@ -83,6 +83,9 @@ sntrup761_dec_fuzz: sntrup761_dec_fuzz.o
sntrup761_enc_fuzz: sntrup761_enc_fuzz.o
$(CXX) -o $@ sntrup761_enc_fuzz.o $(LDFLAGS) $(FUZZ_FLAGS) $(FUZZ_LIBS) -lcrypto
+misc_parse_fuzz: misc_parse_fuzz.o $(SK_NULL_OBJS) $(COMMON_DEPS)
+ $(CXX) -o $@ misc_parse_fuzz.o $(SK_NULL_OBJS) $(LDFLAGS) $(FUZZ_FLAGS) $(LIBS)
+
clean:
-rm -f *.o $(TARGETS)
diff --git a/regress/misc/fuzz-harness/misc_parse_fuzz.cc b/regress/misc/fuzz-harness/misc_parse_fuzz.cc
new file mode 100644
index 000000000..4e7b0636f
--- /dev/null
+++ b/regress/misc/fuzz-harness/misc_parse_fuzz.cc
@@ -0,0 +1,167 @@
+/* Copyright 2026 Google LLC
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+/*
+ * Fuzzer for small string-input parsers across OpenSSH
+ *
+ * Targets: misc.c, addr.c, addrmatch.c, match.c
+ *
+ * Threat model:
+ * - User-supplied CLI arguments (user at host:port, ssh:// URIs, port and
+ * tunnel numbers)
+ * - Admin-supplied patterns in sshd_config / ssh_config (Match Address
+ * CIDR lists, AllowUsers / DenyUsers, AllowGroups, hostname patterns)
+ *
+ * All targeted functions are pure (no inter-call state). Each iteration
+ * invokes every parser exactly once on the same fuzz body in a fixed
+ * source order. The body is split into two substrings at the first
+ * embedded NUL so two-argument matchers can mutate either side.
+ *
+ * Parsers covered:
+ * - parse_user_host_port, parse_uri, convtime, a2port, a2tun,
+ * argv_split + argv_assemble, valid_domain, valid_env_name,
+ * parse_absolute_time (misc.c)
+ * - addr_pton, addr_pton_cidr (addr.c)
+ * - addr_match_list, addr_match_cidr_list (addrmatch.c)
+ * - match_pattern, match_pattern_list, match_hostname,
+ * match_host_and_ip, match_user (match.c)
+ */
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+extern "C" {
+#include "addr.h"
+#include "match.h"
+#include "misc.h"
+#include "log.h"
+}
+
+static int log_initialized = 0;
+
+static char *
+dup_n(const uint8_t *body, size_t blen)
+{
+ char *s = (char *)malloc(blen + 1);
+ if (s == NULL)
+ return NULL;
+ memcpy(s, body, blen);
+ s[blen] = '\0';
+ return s;
+}
+
+static void
+split_two(const uint8_t *body, size_t blen, char **a, char **b)
+{
+ const uint8_t *nul = (const uint8_t *)memchr(body, 0, blen);
+ *a = NULL;
+ *b = NULL;
+ if (nul == NULL) {
+ *a = dup_n(body, blen);
+ *b = strdup("");
+ return;
+ }
+ size_t alen = (size_t)(nul - body);
+ *a = dup_n(body, alen);
+ *b = dup_n(nul + 1, blen - alen - 1);
+}
+
+extern "C" int
+LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+ if (!log_initialized) {
+ log_init("misc_parse_fuzz", SYSLOG_LEVEL_QUIET,
+ SYSLOG_FACILITY_AUTH, 0);
+ log_initialized = 1;
+ }
+ if (size == 0)
+ return 0;
+
+ char *s = dup_n(data, size);
+ char *a = NULL, *b = NULL;
+ split_two(data, size, &a, &b);
+ if (s == NULL || a == NULL || b == NULL) {
+ free(s);
+ free(a);
+ free(b);
+ return 0;
+ }
+
+ {
+ char *u = NULL, *h = NULL;
+ int port = 0;
+ if (parse_user_host_port(s, &u, &h, &port) == 0) {
+ free(u);
+ free(h);
+ }
+ }
+ {
+ char *u = NULL, *h = NULL, *p = NULL;
+ int port = 0;
+ if (parse_uri("ssh", s, &u, &h, &port, &p) == 0) {
+ free(u);
+ free(h);
+ free(p);
+ }
+ }
+ (void)convtime(s);
+ (void)a2port(s);
+ {
+ int tun = 0;
+ (void)a2tun(s, &tun);
+ }
+ {
+ int ac = 0;
+ char **av = NULL;
+ if (argv_split(s, &ac, &av, 1) == 0) {
+ char *back = argv_assemble(ac, av);
+ free(back);
+ argv_free(av, ac);
+ }
+ }
+ {
+ const char *err = NULL;
+ (void)valid_domain(s, 0, &err);
+ }
+ (void)valid_env_name(s);
+ {
+ uint64_t t = 0;
+ (void)parse_absolute_time(s, &t);
+ }
+
+ {
+ struct xaddr n;
+ (void)addr_pton(s, &n);
+ }
+ {
+ struct xaddr n;
+ u_int prefix = 0;
+ (void)addr_pton_cidr(s, &n, &prefix);
+ }
+
+ (void)addr_match_list(a, b);
+ (void)addr_match_cidr_list(a, b);
+ (void)match_pattern(a, b);
+ (void)match_pattern_list(a, b, 0);
+ (void)match_hostname(a, b);
+ (void)match_host_and_ip(a, "127.0.0.1", b);
+ (void)match_user("fuzz", a, "127.0.0.1", b);
+
+ free(s);
+ free(a);
+ free(b);
+ return 0;
+}
--
To stop receiving notification emails like this one, please contact
djm at mindrot.org.
More information about the openssh-commits
mailing list