]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
ec7a02ea ZJS |
2 | |
3 | #include "conf-parser.h" | |
4 | #include "fd-util.h" | |
ec7a02ea ZJS |
5 | #include "fuzz.h" |
6 | #include "install.h" | |
7 | #include "load-fragment.h" | |
2a341bb9 | 8 | #include "manager-dump.h" |
2485b7e2 | 9 | #include "memstream-util.h" |
ec7a02ea | 10 | #include "string-util.h" |
2d3b784d | 11 | #include "unit-serialize.h" |
d6ea3b78 | 12 | #include "utf8.h" |
ec7a02ea ZJS |
13 | |
14 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | |
2485b7e2 | 15 | _cleanup_fclose_ FILE *f = NULL; |
ec7a02ea ZJS |
16 | _cleanup_free_ char *p = NULL; |
17 | UnitType t; | |
18 | _cleanup_(manager_freep) Manager *m = NULL; | |
19 | Unit *u; | |
20 | const char *name; | |
bd0763b6 | 21 | long offset; |
ec7a02ea | 22 | |
c4f883b7 | 23 | if (outside_size_range(size, 0, 65536)) |
7593691a YW |
24 | return 0; |
25 | ||
5df66d7d | 26 | f = data_to_file(data, size); |
7593691a | 27 | |
ec7a02ea ZJS |
28 | assert_se(f); |
29 | ||
30 | if (read_line(f, LINE_MAX, &p) < 0) | |
31 | return 0; | |
32 | ||
33 | t = unit_type_from_string(p); | |
34 | if (t < 0) | |
35 | return 0; | |
36 | ||
37 | if (!unit_vtable[t]->load) | |
38 | return 0; | |
39 | ||
bd0763b6 ZJS |
40 | offset = ftell(f); |
41 | assert_se(offset >= 0); | |
42 | ||
43 | for (;;) { | |
44 | _cleanup_free_ char *l = NULL; | |
af3865ab | 45 | const char *ll; |
bd0763b6 | 46 | |
483ed8a6 | 47 | if (read_line(f, LONG_LINE_MAX, &l) <= 0) |
bd0763b6 ZJS |
48 | break; |
49 | ||
d6ea3b78 ZJS |
50 | ll = startswith(l, UTF8_BYTE_ORDER_MARK) ?: l; |
51 | ll = ll + strspn(ll, WHITESPACE); | |
af3865ab | 52 | |
b834c6ce | 53 | if (HAS_FEATURE_MEMORY_SANITIZER && startswith(ll, "ListenNetlink")) { |
bd0763b6 ZJS |
54 | /* ListenNetlink causes a false positive in msan, |
55 | * let's skip this for now. */ | |
483ed8a6 | 56 | log_notice("Skipping test because ListenNetlink= is present"); |
bd0763b6 | 57 | return 0; |
483ed8a6 | 58 | } |
bd0763b6 ZJS |
59 | } |
60 | ||
61 | assert_se(fseek(f, offset, SEEK_SET) == 0); | |
62 | ||
b872843c ZJS |
63 | /* We don't want to fill the logs with messages about parse errors. |
64 | * Disable most logging if not running standalone */ | |
65 | if (!getenv("SYSTEMD_LOG_LEVEL")) | |
66 | log_set_max_level(LOG_CRIT); | |
67 | ||
4870133b | 68 | assert_se(manager_new(RUNTIME_SCOPE_SYSTEM, MANAGER_TEST_RUN_MINIMAL, &m) >= 0); |
ec7a02ea ZJS |
69 | |
70 | name = strjoina("a.", unit_type_to_string(t)); | |
71 | assert_se(unit_new_for_name(m, unit_vtable[t]->object_size, name, &u) >= 0); | |
72 | ||
4f9ff96a LP |
73 | (void) config_parse( |
74 | name, name, f, | |
75 | UNIT_VTABLE(u)->sections, | |
76 | config_item_perf_lookup, load_fragment_gperf_lookup, | |
7ade8982 | 77 | 0, |
4f9ff96a LP |
78 | u, |
79 | NULL); | |
ec7a02ea | 80 | |
2485b7e2 YW |
81 | _cleanup_(memstream_done) MemStream ms = {}; |
82 | FILE *g; | |
ec7a02ea | 83 | |
2485b7e2 | 84 | assert_se(g = memstream_init(&ms)); |
ec7a02ea | 85 | unit_dump(u, g, ""); |
d1d8786c | 86 | manager_dump(m, g, /* patterns= */ NULL, ">>>"); |
ec7a02ea ZJS |
87 | |
88 | return 0; | |
89 | } |