]>
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" | |
5 | #include "fileio.h" | |
6 | #include "fuzz.h" | |
7 | #include "install.h" | |
8 | #include "load-fragment.h" | |
9 | #include "string-util.h" | |
2d3b784d | 10 | #include "unit-serialize.h" |
d6ea3b78 | 11 | #include "utf8.h" |
ec7a02ea ZJS |
12 | |
13 | int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { | |
14 | _cleanup_free_ char *out = NULL; /* out should be freed after g */ | |
15 | size_t out_size; | |
16 | _cleanup_fclose_ FILE *f = NULL, *g = NULL; | |
17 | _cleanup_free_ char *p = NULL; | |
18 | UnitType t; | |
19 | _cleanup_(manager_freep) Manager *m = NULL; | |
20 | Unit *u; | |
21 | const char *name; | |
bd0763b6 | 22 | long offset; |
ec7a02ea ZJS |
23 | |
24 | if (size == 0) | |
25 | return 0; | |
26 | ||
673a1e6f | 27 | f = fmemopen_unlocked((char*) data, size, "re"); |
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 | ||
ec7a02ea ZJS |
68 | assert_se(manager_new(UNIT_FILE_SYSTEM, MANAGER_TEST_RUN_MINIMAL, &m) >= 0); |
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 | |
673a1e6f | 81 | g = open_memstream_unlocked(&out, &out_size); |
ec7a02ea ZJS |
82 | assert_se(g); |
83 | ||
84 | unit_dump(u, g, ""); | |
4832ce7e | 85 | manager_dump(m, g, ">>>"); |
ec7a02ea ZJS |
86 | |
87 | return 0; | |
88 | } |