1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
12 static int json_dispatch_config(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
13 BootConfig
*config
= ASSERT_PTR(userdata
);
15 const char *s
= json_variant_string(variant
);
19 _cleanup_fclose_
FILE *f
= NULL
;
20 assert_se(f
= data_to_file((const uint8_t*) s
, strlen(s
)));
22 (void) boot_loader_read_conf(config
, f
, "memstream");
26 static int json_dispatch_entries(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
27 BootConfig
*config
= ASSERT_PTR(userdata
);
30 JSON_VARIANT_ARRAY_FOREACH(entry
, variant
) {
31 if (!json_variant_is_array(entry
) ||
32 json_variant_elements(entry
) < 1)
36 const char *id
= NULL
, *raw
= NULL
;
37 _cleanup_free_
char *data
= NULL
;
38 ssize_t len
= -ENODATA
;
40 v
= json_variant_by_index(entry
, 0);
42 id
= json_variant_string(v
);
46 v
= json_variant_by_index(entry
, 1);
48 raw
= json_variant_string(v
);
50 len
= cunescape(raw
, UNESCAPE_RELAX
| UNESCAPE_ACCEPT_NUL
, &data
);
52 _cleanup_fclose_
FILE *f
= NULL
;
53 assert_se(f
= data_to_file((const uint8_t*) data
, len
));
55 assert_se(boot_config_load_type1(config
, f
, "/", "/entries", id
) != -ENOMEM
);
62 static int json_dispatch_loader(const char *name
, JsonVariant
*variant
, JsonDispatchFlags flags
, void *userdata
) {
63 BootConfig
*config
= ASSERT_PTR(userdata
);
64 _cleanup_strv_free_
char **entries
= NULL
;
67 r
= json_dispatch_strv(name
, variant
, flags
, &entries
);
71 (void) boot_config_augment_from_loader(config
, entries
, false);
75 static const JsonDispatch data_dispatch
[] = {
76 { "config", JSON_VARIANT_STRING
, json_dispatch_config
, 0, 0 },
77 { "entries", JSON_VARIANT_ARRAY
, json_dispatch_entries
, 0, 0 },
78 { "loader", JSON_VARIANT_ARRAY
, json_dispatch_loader
, 0, 0 },
82 int LLVMFuzzerTestOneInput(const uint8_t *data
, size_t size
) {
83 _cleanup_free_
const char *datadup
= NULL
;
84 _cleanup_(boot_config_free
) BootConfig config
= BOOT_CONFIG_NULL
;
87 if (outside_size_range(size
, 0, 65536))
90 /* Disable most logging if not running standalone */
91 if (!getenv("SYSTEMD_LOG_LEVEL"))
92 log_set_max_level(LOG_CRIT
);
94 assert_se(datadup
= memdup_suffix0(data
, size
));
96 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
97 r
= json_parse(datadup
, 0, &v
, NULL
, NULL
);
101 r
= json_dispatch(v
, data_dispatch
, NULL
, 0, &config
);
105 assert_se(boot_config_finalize(&config
) >= 0);
107 (void) boot_config_select_special_entries(&config
, /* skip_efivars= */ false);
109 _cleanup_close_
int orig_stdout_fd
= -EBADF
;
110 if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0) {
111 orig_stdout_fd
= fcntl(fileno(stdout
), F_DUPFD_CLOEXEC
, 3);
112 if (orig_stdout_fd
< 0)
113 log_warning_errno(orig_stdout_fd
, "Failed to duplicate fd 1: %m");
115 assert_se(freopen("/dev/null", "w", stdout
));
118 (void) show_boot_entries(&config
, JSON_FORMAT_OFF
);
119 (void) show_boot_entries(&config
, JSON_FORMAT_PRETTY
);
121 if (orig_stdout_fd
>= 0)
122 assert_se(freopen(FORMAT_PROC_FD_PATH(orig_stdout_fd
), "w", stdout
));