Coverage Report

Created: 2026-10-23 07:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openssh/regress/misc/fuzz-harness/hostfile_fuzz.cc
Line
Count
Source
1
/* Copyright 2026 Google LLC
2
Licensed under the Apache License, Version 2.0 (the "License");
3
you may not use this file except in compliance with the License.
4
You may obtain a copy of the License at
5
     http://www.apache.org/licenses/LICENSE-2.0
6
Unless required by applicable law or agreed to in writing, software
7
distributed under the License is distributed on an "AS IS" BASIS,
8
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
See the License for the specific language governing permissions and
10
limitations under the License.
11
*/
12
13
#include <stdio.h>
14
#include <stddef.h>
15
#include <stdint.h>
16
#include <stdlib.h>
17
#include <string.h>
18
19
extern "C" {
20
21
#include "hostfile.h"
22
#include "sshkey.h"
23
#include "log.h"
24
25
static int log_initialized = 0;
26
27
static int
28
noop_cb(struct hostkey_foreach_line *l, void *ctx)
29
90.7k
{
30
90.7k
  (void)l; (void)ctx;
31
90.7k
  return 0;
32
90.7k
}
33
34
int
35
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
36
1.85k
{
37
1.85k
  if (!log_initialized) {
38
1
    log_init("hostfile_fuzz", SYSLOG_LEVEL_QUIET,
39
1
        SYSLOG_FACILITY_AUTH, 0);
40
1
    log_initialized = 1;
41
1
  }
42
43
  /* Drive every HKF_WANT_* combination on each input. */
44
1.85k
  static const u_int flag_combos[] = {
45
1.85k
    0,
46
1.85k
    HKF_WANT_MATCH,
47
1.85k
    HKF_WANT_PARSE_KEY,
48
1.85k
    HKF_WANT_MATCH | HKF_WANT_PARSE_KEY,
49
1.85k
  };
50
9.28k
  for (size_t i = 0; i < sizeof(flag_combos)/sizeof(flag_combos[0]); i++) {
51
7.42k
    FILE *f = fmemopen((void *)data, size, "r");
52
7.42k
    if (f == NULL)
53
0
      continue;
54
7.42k
    const char *host = (flag_combos[i] & HKF_WANT_MATCH) ?
55
7.42k
        "example.com" : NULL;
56
7.42k
    (void)hostkeys_foreach_file("/fuzz", f, noop_cb, NULL,
57
7.42k
        host, "127.0.0.1", flag_combos[i], 0);
58
7.42k
    fclose(f);
59
7.42k
  }
60
61
  /* Higher-level wrapper that adds record_hostkey on top of foreach. */
62
1.85k
  {
63
1.85k
    FILE *f = fmemopen((void *)data, size, "r");
64
1.85k
    if (f != NULL) {
65
1.85k
      struct hostkeys *hk = init_hostkeys();
66
1.85k
      if (hk != NULL) {
67
1.85k
        load_hostkeys_file(hk, "example.com",
68
1.85k
            "/fuzz", f, 0);
69
1.85k
        free_hostkeys(hk);
70
1.85k
      }
71
1.85k
      fclose(f);
72
1.85k
    }
73
1.85k
  }
74
75
  /* Drive host_hash + extract_salt on a bounded hostname-shaped slice. */
76
1.85k
  if (size > 0) {
77
1.85k
    size_t n = size < 256 ? size : 256;
78
1.85k
    char *hb = (char *)malloc(n + 1);
79
1.85k
    if (hb != NULL) {
80
1.85k
      memcpy(hb, data, n);
81
1.85k
      hb[n] = '\0';
82
1.85k
      char *h = host_hash("example.com", hb, 0);
83
1.85k
      free(h);
84
1.85k
      free(hb);
85
1.85k
    }
86
1.85k
  }
87
88
1.85k
  return 0;
89
1.85k
}
90
91
} // extern "C"