]>
Commit | Line | Data |
---|---|---|
b012e921 MB |
1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
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" | |
10 | #include "unit.h" | |
11 | #include "utf8.h" | |
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; | |
22 | long offset; | |
23 | ||
24 | if (size == 0) | |
25 | return 0; | |
26 | ||
27 | f = fmemopen((char*) data, size, "re"); | |
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 | ||
40 | offset = ftell(f); | |
41 | assert_se(offset >= 0); | |
42 | ||
43 | for (;;) { | |
44 | _cleanup_free_ char *l = NULL; | |
45 | const char *ll; | |
46 | ||
47 | if (read_line(f, LONG_LINE_MAX, &l) <= 0) | |
48 | break; | |
49 | ||
50 | ll = startswith(l, UTF8_BYTE_ORDER_MARK) ?: l; | |
51 | ll = ll + strspn(ll, WHITESPACE); | |
52 | ||
53 | if (HAS_FEATURE_MEMORY_SANITIZER && startswith(ll, "ListenNetlink")) { | |
54 | /* ListenNetlink causes a false positive in msan, | |
55 | * let's skip this for now. */ | |
56 | log_notice("Skipping test because ListenNetlink= is present"); | |
57 | return 0; | |
58 | } | |
59 | } | |
60 | ||
61 | assert_se(fseek(f, offset, SEEK_SET) == 0); | |
62 | ||
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 | ||
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 | ||
73 | (void) config_parse(name, name, f, | |
74 | UNIT_VTABLE(u)->sections, | |
75 | config_item_perf_lookup, load_fragment_gperf_lookup, | |
76 | CONFIG_PARSE_ALLOW_INCLUDE, u); | |
77 | ||
78 | g = open_memstream(&out, &out_size); | |
79 | assert_se(g); | |
80 | ||
81 | unit_dump(u, g, ""); | |
bb4f798a | 82 | manager_dump(m, g, ">>>"); |
b012e921 MB |
83 | |
84 | return 0; | |
85 | } |