/src/openssh/regress/misc/fuzz-harness/sshconfig_fuzz.cc
Line | Count | Source |
1 | | // libfuzzer driver for SSH client configuration file parser. |
2 | | // Covers readconf.c: process_config_line_depth() and related parsing logic. |
3 | | |
4 | | #include <sys/types.h> |
5 | | #include <stdio.h> |
6 | | #include <stdint.h> |
7 | | #include <stdlib.h> |
8 | | #include <string.h> |
9 | | #include <pwd.h> |
10 | | #include <unistd.h> |
11 | | |
12 | | extern "C" { |
13 | | |
14 | | #include "includes.h" |
15 | | #include "ssh.h" |
16 | | #include "misc.h" |
17 | | #include "log.h" |
18 | | #include "readconf.h" |
19 | | #include "xmalloc.h" |
20 | | |
21 | | // Stub out log output to reduce noise |
22 | 0 | void sshsig_free(struct sshsig_ctx *ctx) {} |
23 | | |
24 | | } // extern "C" |
25 | | |
26 | | static struct passwd fuzz_pw; |
27 | | static char fuzz_username[] = "fuzzer"; |
28 | | static char fuzz_home[] = "/tmp"; |
29 | | static char fuzz_shell[] = "/bin/sh"; |
30 | | |
31 | 1 | static void init_pw(void) { |
32 | 1 | fuzz_pw.pw_name = fuzz_username; |
33 | 1 | fuzz_pw.pw_uid = getuid(); |
34 | 1 | fuzz_pw.pw_gid = getgid(); |
35 | 1 | fuzz_pw.pw_dir = fuzz_home; |
36 | 1 | fuzz_pw.pw_shell = fuzz_shell; |
37 | 1 | } |
38 | | |
39 | 285 | extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { |
40 | 285 | static int initialized = 0; |
41 | 285 | if (!initialized) { |
42 | 1 | log_init("sshconfig_fuzz", SYSLOG_LEVEL_QUIET, SYSLOG_FACILITY_AUTH, 0); |
43 | 1 | init_pw(); |
44 | 1 | initialized = 1; |
45 | 1 | } |
46 | | |
47 | | // Write fuzz input to a temp file (read_config_file requires a path) |
48 | 285 | char tmpfile[] = "/tmp/sshconfig_fuzz_XXXXXX"; |
49 | 285 | int fd = mkstemp(tmpfile); |
50 | 285 | if (fd < 0) |
51 | 0 | return 0; |
52 | | |
53 | 285 | if (write(fd, data, size) != (ssize_t)size) { |
54 | 0 | close(fd); |
55 | 0 | unlink(tmpfile); |
56 | 0 | return 0; |
57 | 0 | } |
58 | 285 | close(fd); |
59 | | |
60 | 285 | Options options; |
61 | 285 | initialize_options(&options); |
62 | | |
63 | | // Process each line through the config parser |
64 | | // Errors are intentional (fuzzing) — suppress but don't crash |
65 | 285 | read_config_file(tmpfile, &fuzz_pw, "fuzz.example.com", "fuzz.example.com", |
66 | 285 | NULL, &options, 0, NULL); |
67 | | |
68 | | // Clean up allocated options |
69 | | // (options cleanup is intentionally omitted; leak sanitizer disabled for fuzzing) |
70 | | |
71 | 285 | unlink(tmpfile); |
72 | 285 | return 0; |
73 | 285 | } |