mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
This adds the ExtraFileDescriptor property to StartTransient dbus API with format "a(hs)" - array of (file descriptor, name) pairs. The FD will be passed to the unit via sd_notify like Socket and OpenFile. systemctl show also shows ExtraFileDescriptorName for these transient units. We only show the name passed to dbus as the FD numbers will change once passed over the unix socket and are duplicated, so its confusing to display the numbers. We do not add this functionality for systemd-run or general systemd service units as it is not useful for general systemd services. Arguably, it could be useful for systemd-run in bash scripts but we prefer to be cautious and not expose the API yet. Fixes: #34396
90 lines
3.4 KiB
C
90 lines
3.4 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
/* Notes on how to run the fuzzer manually:
|
|
* 1) Build the fuzzers with LLVM's libFuzzer and ASan+UBSan:
|
|
* $ CC=clang CXX=clang++ meson build-libfuzz -Db_sanitize=address,undefined -Dllvm-fuzz=true -Db_lundef=false
|
|
*
|
|
* 2) Collect some valid inputs:
|
|
*
|
|
* OUT=test/fuzz/fuzz-execute-serialize/initial
|
|
* for section in context command parameters runtime cgroup; do
|
|
* awk "match(\$0, /startswith\\(.+, \"(exec-${section}-[^\"]+=)\"/, m) { print m[1]; }" \
|
|
* src/core/execute-serialize.c >>"$OUT"
|
|
* # Each "section" is delimited by an empty line
|
|
* echo >>"$OUT"
|
|
* done
|
|
*
|
|
* 3) Run the fuzzer:
|
|
* $ build-libfuzz/fuzz-execute-serialize test/fuzz/fuzz-execute-serialize
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
|
|
#include "alloc-util.h"
|
|
#include "execute-serialize.h"
|
|
#include "fd-util.h"
|
|
#include "fuzz.h"
|
|
#include "service.h"
|
|
|
|
static void exec_fuzz_one(FILE *f, FDSet *fdset) {
|
|
_cleanup_(exec_params_deep_clear) ExecParameters params = EXEC_PARAMETERS_INIT(/* flags= */ 0);
|
|
_cleanup_(exec_context_done) ExecContext exec_context = {};
|
|
_cleanup_(cgroup_context_done) CGroupContext cgroup_context = {};
|
|
DynamicCreds dynamic_creds = {};
|
|
ExecCommand command = {};
|
|
ExecSharedRuntime shared = {
|
|
.netns_storage_socket = EBADF_PAIR,
|
|
.ipcns_storage_socket = EBADF_PAIR,
|
|
};
|
|
ExecRuntime runtime = {
|
|
.ephemeral_storage_socket = EBADF_PAIR,
|
|
.shared = &shared,
|
|
.dynamic_creds = &dynamic_creds,
|
|
};
|
|
|
|
exec_context_init(&exec_context);
|
|
cgroup_context_init(&cgroup_context);
|
|
|
|
(void) exec_deserialize_invocation(f, fdset, &exec_context, &command, ¶ms, &runtime, &cgroup_context);
|
|
(void) exec_serialize_invocation(f, fdset, &exec_context, &command, ¶ms, &runtime, &cgroup_context);
|
|
(void) exec_deserialize_invocation(f, fdset, &exec_context, &command, ¶ms, &runtime, &cgroup_context);
|
|
|
|
/* We definitely didn't provide valid FDs during deserialization, so
|
|
* wipe the FDs before exec_params_serialized_clear() kicks in, otherwise
|
|
* we'll hit the assert in safe_close() */
|
|
params.stdin_fd = -EBADF;
|
|
params.stdout_fd = -EBADF;
|
|
params.stderr_fd = -EBADF;
|
|
params.exec_fd = -EBADF;
|
|
params.user_lookup_fd = -EBADF;
|
|
params.bpf_restrict_fs_map_fd = -EBADF;
|
|
if (!params.fds)
|
|
params.n_socket_fds = params.n_storage_fds = params.n_extra_fds = 0;
|
|
for (size_t i = 0; params.fds && i < params.n_socket_fds + params.n_storage_fds + params.n_extra_fds; i++)
|
|
params.fds[i] = -EBADF;
|
|
|
|
exec_command_done_array(&command, /* n= */ 1);
|
|
exec_shared_runtime_done(&shared);
|
|
if (dynamic_creds.group != dynamic_creds.user)
|
|
dynamic_user_free(dynamic_creds.group);
|
|
dynamic_user_free(dynamic_creds.user);
|
|
free(runtime.ephemeral_copy);
|
|
safe_close_pair(runtime.ephemeral_storage_socket);
|
|
}
|
|
|
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
|
_cleanup_fclose_ FILE *f = NULL;
|
|
_cleanup_fdset_free_ FDSet *fdset = NULL;
|
|
|
|
if (outside_size_range(size, 0, 128 * 1024))
|
|
return 0;
|
|
|
|
fuzz_setup_logging();
|
|
|
|
assert_se(fdset = fdset_new());
|
|
assert_se(f = data_to_file(data, size));
|
|
|
|
exec_fuzz_one(f, fdset);
|
|
|
|
return 0;
|
|
}
|