mirror of
https://github.com/systemd/systemd.git
synced 2024-10-28 11:55:44 +03:00
Add fuzzer for the bootspec parser
This commit is contained in:
parent
a847b539de
commit
1409ce6ed2
18
src/fuzz/fuzz-bootspec-gen.py
Normal file
18
src/fuzz/fuzz-bootspec-gen.py
Normal file
@ -0,0 +1,18 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
"""Generate sample input for fuzz-bootspec"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
config = open(sys.argv[1]).read()
|
||||
entries = [(os.path.basename(name), open(name).read())
|
||||
for name in sys.argv[2:]]
|
||||
|
||||
data = {
|
||||
'config': config,
|
||||
'entries': entries,
|
||||
}
|
||||
|
||||
print(json.dumps(data, indent=4))
|
108
src/fuzz/fuzz-bootspec.c
Normal file
108
src/fuzz/fuzz-bootspec.c
Normal file
@ -0,0 +1,108 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "bootspec.h"
|
||||
#include "env-util.h"
|
||||
#include "escape.h"
|
||||
#include "fuzz.h"
|
||||
#include "fd-util.h"
|
||||
#include "json.h"
|
||||
|
||||
static int json_dispatch_config(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
|
||||
BootConfig *config = ASSERT_PTR(userdata);
|
||||
|
||||
const char *s = json_variant_string(variant);
|
||||
if (!s)
|
||||
return -EINVAL;
|
||||
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
assert_se(f = data_to_file((const uint8_t*) s, strlen(s)));
|
||||
|
||||
(void) boot_loader_read_conf(config, f, "memstream");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int json_dispatch_entries(const char *name, JsonVariant *variant, JsonDispatchFlags flags, void *userdata) {
|
||||
BootConfig *config = ASSERT_PTR(userdata);
|
||||
JsonVariant *entry;
|
||||
|
||||
JSON_VARIANT_ARRAY_FOREACH(entry, variant) {
|
||||
if (!json_variant_is_array(entry) ||
|
||||
json_variant_elements(entry) < 1)
|
||||
return -EINVAL;
|
||||
|
||||
JsonVariant *v;
|
||||
const char *id = NULL, *raw = NULL;
|
||||
_cleanup_free_ char *data = NULL;
|
||||
ssize_t len = -ENODATA;
|
||||
|
||||
v = json_variant_by_index(entry, 0);
|
||||
if (v)
|
||||
id = json_variant_string(v);
|
||||
if (!id)
|
||||
continue;
|
||||
|
||||
v = json_variant_by_index(entry, 1);
|
||||
if (v)
|
||||
raw = json_variant_string(v);
|
||||
if (raw)
|
||||
len = cunescape(raw, UNESCAPE_RELAX | UNESCAPE_ACCEPT_NUL, &data);
|
||||
if (len >= 0) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
assert_se(f = data_to_file((const uint8_t*) data, len));
|
||||
|
||||
assert_se(boot_config_load_type1(config, f, "/", "/entries", id) != -ENOMEM);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const JsonDispatch data_dispatch[] = {
|
||||
{ "config", JSON_VARIANT_STRING, json_dispatch_config, 0, 0 },
|
||||
{ "entries", JSON_VARIANT_ARRAY, json_dispatch_entries, 0, 0 },
|
||||
{}
|
||||
};
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
_cleanup_free_ const char *datadup = NULL;
|
||||
_cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL;
|
||||
int r;
|
||||
|
||||
/* Disable most logging if not running standalone */
|
||||
if (!getenv("SYSTEMD_LOG_LEVEL"))
|
||||
log_set_max_level(LOG_CRIT);
|
||||
|
||||
assert_se(datadup = memdup_suffix0(data, size));
|
||||
|
||||
_cleanup_(json_variant_unrefp) JsonVariant *v = NULL;
|
||||
r = json_parse(datadup, 0, &v, NULL, NULL);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
r = json_dispatch(v, data_dispatch, NULL, 0, &config);
|
||||
if (r < 0)
|
||||
return 0;
|
||||
|
||||
assert_se(boot_config_finalize(&config) >= 0);
|
||||
|
||||
(void) boot_config_select_special_entries(&config);
|
||||
|
||||
_cleanup_close_ int orig_stdout_fd = -1;
|
||||
if (getenv_bool("SYSTEMD_FUZZ_OUTPUT") <= 0) {
|
||||
orig_stdout_fd = fcntl(fileno(stdout), F_DUPFD_CLOEXEC, 3);
|
||||
if (orig_stdout_fd < 0)
|
||||
log_warning_errno(orig_stdout_fd, "Failed to duplicate fd 1: %m");
|
||||
else
|
||||
assert_se(freopen("/dev/null", "w", stdout));
|
||||
}
|
||||
|
||||
(void) show_boot_entries(&config, JSON_FORMAT_OFF);
|
||||
(void) show_boot_entries(&config, JSON_FORMAT_PRETTY);
|
||||
|
||||
if (orig_stdout_fd >= 0)
|
||||
assert_se(freopen(FORMAT_PROC_FD_PATH(orig_stdout_fd), "w", stdout));
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
fuzzers += [
|
||||
[files('fuzz-bootspec.c')],
|
||||
|
||||
[files('fuzz-bus-label.c')],
|
||||
|
||||
[files('fuzz-calendarspec.c')],
|
||||
|
17
test/fuzz/fuzz-bootspec/sample1
Normal file
17
test/fuzz/fuzz-bootspec/sample1
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"config": "timeout 3\nconsole-mode 2\n# default 08a5690afeedfeedaaac0a5d2e3cf6b0-*\n# default auto-reboot-to-firmware-setup\n",
|
||||
"entries": [
|
||||
[
|
||||
"08a5690afeedfeedaaac0a5d2e3cf6b0-5.15.14-200.fc35.x86_64.conf",
|
||||
"title Fedora Linux 35 (Workstation Edition)\nversion 5.15.14-200.fc35.x86_64\nmachine-id 08a5690afeedfeedaaac0a5d2e3cf6b0\noptions root=/dev/mapper/fedora_krowka-root rw rd.lvm.lv=fedora_krowka/root rd.luks.uuid=luks-2d9b648a-15b1-4204-988b-ec085089f8ce rd.lvm.lv=fedora_krowka/swap LANG=en_US.UTF-8 selinux=0 resume=/dev/mapper/fedora_krowka-swap systemd.show-status systemd.unit-status-format=name quiet\nlinux /08a5690afeedfeedaaac0a5d2e3cf6b0/5.15.14-200.fc35.x86_64/linux\ninitrd /08a5690afeedfeedaaac0a5d2e3cf6b0/5.15.14-200.fc35.x86_64/initrd\n"
|
||||
],
|
||||
[
|
||||
"08a5690afeedfeedaaac0a5d2e3cf6b0-5.17.0-0.rc5.102.fc36.x86_64.conf",
|
||||
"title Fedora Linux 36 (Workstation Edition Prerelease)\nversion 5.17.0-0.rc5.102.fc36.x86_64\nmachine-id 08a5690afeedfeedaaac0a5d2e3cf6b0\noptions root=/dev/mapper/fedora_krowka-root rw rd.lvm.lv=fedora_krowka/root rd.luks.uuid=luks-2d9b648a-15b1-4204-988b-ec085089f8ce rd.lvm.lv=fedora_krowka/swap LANG=en_US.UTF-8 selinux=0 resume=/dev/mapper/fedora_krowka-swap systemd.show-status systemd.unit-status-format=name quiet\nlinux /08a5690afeedfeedaaac0a5d2e3cf6b0/5.17.0-0.rc5.102.fc36.x86_64/linux\ninitrd /08a5690afeedfeedaaac0a5d2e3cf6b0/5.17.0-0.rc5.102.fc36.x86_64/initrd\n"
|
||||
],
|
||||
[
|
||||
"listing.conf",
|
||||
"title Title\nversion 3.7.2-201.fc18.x86_64\nmachine-id 4098b3f648d74c13b1f04ccfba7798e8\nsort-key 666\nlinux /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/linux\ninitrd /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/initrd\nefi /6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.x86_64/efi\noptions one two three four\ndevicetree 6a9857a393724b7a981ebb5b8495b9ea/3.8.0-2.fc19.armv7hl/tegra20-paz00.dtb\ndevicetree-overlay /6a9857a393724b7a981ebb5b8495b9ea/overlays/overlay_A.dtbo /6a9857a393724b7a981ebb5b8495b9ea/overlays/overlay_B.dtbo\narchitecture IA32\narchitecture x64\narchitecture IA64\narchitecture ARM\narchitecture AA64\n"
|
||||
]
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user