libc,shared: detect newer library symbols at runtime
For libc syscall wrappers (pidfd_open, fsopen, openat2, etc.) we previously gated the calls behind build-time HAVE_* checks. Replace these with shim functions in src/libc/ that fall back to the raw syscall at runtime when the loaded glibc lacks the symbol. The infrastructure lives in src/libc/libc-shim.h: DEFINE_SYSCALL_SHIM falls back to a direct syscall, DEFINE_LIBC_SHIM returns ENOSYS (for posix_spawn-family helpers that have no corresponding syscall), and DEFINE_LIBC_ERRNO_SHIM sets errno=ENOSYS and returns -1 (for read/write-style helpers). The weak reference to the libc symbol is bound via __asm__(\"name\") rename so the bare libc identifier never appears as a C token — this avoids both #undef boilerplate against override-header redirects and the resulting -Wredundant-decls warning. Drop the corresponding cc.has_function() loop from meson.build. For optional libraries (libcryptsetup, libdw, libarchive), drop the per-symbol HAVE_* checks. Always declare the prototypes, suppressing the redundant-decl warnings via DISABLE_WARNING_REDUNDANT_DECLS and NOLINT, and resolve the symbols after the main dlopen via a new DLSYM_OPTIONAL() helper that only assigns on success. libcryptsetup's crypt_set_keyring_to_link / crypt_token_set_external_path and libarchive's *_is_set wrappers use fallback functions as their pointer initializers (returning -ENOSYS and 0 respectively), so call sites can invoke the symbol unconditionally and just check for -ENOSYS where the \"not supported\" distinction matters. The same shim treatment applies to pidfd_spawn / posix_spawnattr_setcgroup_np (src/libc/spawn.c) and epoll_pwait2 (src/libc/epoll.c), with corresponding override headers in src/include/override/spawn.h and src/include/override/sys/epoll.h. posix_spawn_wrapper() in process-util.c and epoll_wait_usec() in sd-event.c now detect ENOSYS in the return value instead of checking the function pointer, falling back to plain posix_spawn() and epoll_wait() respectively. coredump-config and coredump-submit get a dlopen_dw_has_dwfl_set_sysroot() helper. The kexec arch gate now uses defined(__NR_kexec_file_load) directly; pidfd.h uses __has_include_next() to decide whether to pull in glibc's header. This lets binaries built against newer glibc / libcryptsetup / libdw / libarchive headers still load and run on older targets where these symbols are absent.
This commit is contained in:
-63
@@ -582,43 +582,6 @@ long_max = cc.compute_int(
|
||||
assert(long_max > 100000)
|
||||
conf.set_quoted('LONG_MAX_STR', f'@long_max@')
|
||||
|
||||
foreach ident : [
|
||||
['renameat2', '''#include <stdio.h>'''], # since musl-1.2.6
|
||||
['set_mempolicy', '''#include <sys/syscall.h>'''], # declared at numaif.h provided by libnuma, which we do not use
|
||||
['get_mempolicy', '''#include <sys/syscall.h>'''], # declared at numaif.h provided by libnuma, which we do not use
|
||||
['epoll_pwait2', '''#include <sys/epoll.h>'''], # since glibc-2.35
|
||||
['fsconfig', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||
['fsmount', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||
['fsopen', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||
['mount_setattr', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||
['move_mount', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||
['open_tree', '''#include <sys/mount.h>'''], # since glibc-2.36
|
||||
['openat2', '''#include <fcntl.h>'''], # since glibc-2.42
|
||||
['pidfd_open', '''#include <sys/pidfd.h>'''], # since glibc-2.36
|
||||
['pidfd_send_signal', '''#include <sys/pidfd.h>'''], # since glibc-2.36
|
||||
['pidfd_spawn', '''#include <spawn.h>'''], # since glibc-2.39
|
||||
['sched_setattr', '''#include <sched.h>'''], # since glibc-2.41
|
||||
['ioprio_get', '''#include <sched.h>'''], # no known header declares ioprio_get
|
||||
['ioprio_set', '''#include <sched.h>'''], # no known header declares ioprio_set
|
||||
['rt_tgsigqueueinfo', '''#include <signal.h>'''], # no known header declares rt_tgsigqueueinfo
|
||||
['open_tree_attr', '''#include <sys/mount.h>'''], # no known header declares open_tree_attr
|
||||
['quotactl_fd', '''#include <sys/quota.h>'''], # no known header declares quotactl_fd
|
||||
['fchmodat2', '''#include <sys/stat.h>'''], # no known header declares fchmodat2
|
||||
['bpf', '''#include <sys/syscall.h>'''], # no known header declares bpf
|
||||
['kcmp', '''#include <sys/syscall.h>'''], # no known header declares kcmp
|
||||
['kexec_file_load', '''#include <sys/syscall.h>'''], # no known header declares kexec_file_load
|
||||
['keyctl', '''#include <sys/syscall.h>'''], # no known header declares keyctl
|
||||
['add_key', '''#include <sys/syscall.h>'''], # no known header declares add_key
|
||||
['request_key', '''#include <sys/syscall.h>'''], # no known header declares request_key
|
||||
['setxattrat', '''#include <sys/xattr.h>'''], # no known header declares setxattrat
|
||||
['removexattrat', '''#include <sys/xattr.h>'''], # no known header declares removexattrat
|
||||
['pivot_root', '''#include <unistd.h>'''], # no known header declares pivot_root
|
||||
]
|
||||
|
||||
have = cc.has_function(ident[0], prefix : ident[1], args : '-D_GNU_SOURCE')
|
||||
conf.set10('HAVE_' + ident[0].to_upper(), have)
|
||||
endforeach
|
||||
|
||||
#####################################################################
|
||||
|
||||
awk = find_program('awk')
|
||||
@@ -1203,18 +1166,6 @@ conf.set10('HAVE_LIBCRYPTSETUP', have)
|
||||
conf.set10('HAVE_LIBCRYPTSETUP_PLUGINS',
|
||||
libcryptsetup_plugins.allowed() and have)
|
||||
|
||||
foreach ident : [
|
||||
'crypt_set_keyring_to_link', # 2.7
|
||||
'crypt_token_set_external_path', # 2.7
|
||||
]
|
||||
|
||||
have_ident = have and cc.has_function(
|
||||
ident,
|
||||
prefix : '#include <libcryptsetup.h>',
|
||||
dependencies : libcryptsetup)
|
||||
conf.set10('HAVE_' + ident.to_upper(), have_ident)
|
||||
endforeach
|
||||
|
||||
libcurl = dependency('libcurl',
|
||||
version : '>= 7.32.0',
|
||||
required : get_option('libcurl'))
|
||||
@@ -1292,10 +1243,6 @@ libelf = dependency('libelf',
|
||||
libelf_cflags = libelf.partial_dependency(includes: true, compile_args: true)
|
||||
conf.set10('HAVE_ELFUTILS', libdw.found() and libelf.found())
|
||||
|
||||
# New in elfutils 0.192
|
||||
conf.set10('HAVE_DWFL_SET_SYSROOT',
|
||||
libdw.found() and cc.has_function('dwfl_set_sysroot', dependencies : libdw))
|
||||
|
||||
libz = dependency('zlib',
|
||||
required : get_option('zlib'))
|
||||
conf.set10('HAVE_ZLIB', libz.found())
|
||||
@@ -1365,16 +1312,6 @@ libarchive = dependency('libarchive',
|
||||
libarchive_cflags = libarchive.partial_dependency(includes: true, compile_args: true)
|
||||
conf.set10('HAVE_LIBARCHIVE', libarchive.found())
|
||||
|
||||
foreach ident : [
|
||||
'archive_entry_gid_is_set', # since 3.7.3
|
||||
'archive_entry_uid_is_set', # since 3.7.3
|
||||
'archive_entry_hardlink_is_set', # since 3.7.5
|
||||
]
|
||||
|
||||
have = libarchive.found() and cc.has_function(ident, dependencies : libarchive)
|
||||
conf.set10('HAVE_' + ident.to_upper(), have)
|
||||
endforeach
|
||||
|
||||
libxkbcommon = dependency('xkbcommon',
|
||||
version : '>= 0.3.0',
|
||||
required : get_option('xkbcommon'))
|
||||
|
||||
@@ -33,6 +33,19 @@ int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_l
|
||||
#define DLSYM_ARG_FORCE(arg) \
|
||||
&sym_##arg, STRINGIFY(arg)
|
||||
|
||||
/* Resolve a single optional symbol from an already-opened library handle. The pointer variable is expected
|
||||
* to be named sym_<name> (same convention as DLSYM_ARG). Only assigns on success, so the pointer keeps its
|
||||
* pre-existing value if the symbol is not present — useful for fallback initialization. dlerror() is
|
||||
* cleared first so callers can distinguish "symbol not found" from "symbol's value is NULL" by checking
|
||||
* dlerror() after; for function symbols (which can never be NULL on success) the _v check below is
|
||||
* sufficient. */
|
||||
#define DLSYM_OPTIONAL(dl, name) \
|
||||
({ \
|
||||
(void) dlerror(); \
|
||||
typeof(sym_##name) _v = (typeof(sym_##name)) dlsym((dl), #name); \
|
||||
if (_v) sym_##name = _v; \
|
||||
})
|
||||
|
||||
/* If called dlopen_many_sym_or_warn() will fail with EPERM. This can be used to block lazy loading of shared
|
||||
* libs, if we transfer a process into a different namespace. Note that this does not work for all calls of
|
||||
* dlopen(), just those through our dlopen_safe() wrapper (which we use comprehensively in our
|
||||
|
||||
+14
-13
@@ -2047,7 +2047,6 @@ int posix_spawn_wrapper(
|
||||
/* Initialization needs to succeed before we can set up a destructor. */
|
||||
_unused_ _cleanup_(posix_spawnattr_destroyp) posix_spawnattr_t *attr_destructor = &attr;
|
||||
|
||||
#if HAVE_PIDFD_SPAWN
|
||||
static bool have_clone_into_cgroup = true; /* kernel 5.7+ */
|
||||
_cleanup_close_ int cgroup_fd = -EBADF;
|
||||
|
||||
@@ -2063,12 +2062,13 @@ int posix_spawn_wrapper(
|
||||
return -errno;
|
||||
|
||||
r = posix_spawnattr_setcgroup_np(&attr, cgroup_fd);
|
||||
if (r != 0)
|
||||
if (r == 0)
|
||||
flags |= POSIX_SPAWN_SETCGROUP;
|
||||
else if (r != ENOSYS)
|
||||
return -r;
|
||||
|
||||
flags |= POSIX_SPAWN_SETCGROUP;
|
||||
/* If libc lacks posix_spawnattr_setcgroup_np we silently skip POSIX_SPAWN_SETCGROUP — the
|
||||
* caller will then need to attach the child to the cgroup themselves. */
|
||||
}
|
||||
#endif
|
||||
|
||||
r = posix_spawnattr_setflags(&attr, flags);
|
||||
if (r != 0)
|
||||
@@ -2077,7 +2077,6 @@ int posix_spawn_wrapper(
|
||||
if (r != 0)
|
||||
return -r;
|
||||
|
||||
#if HAVE_PIDFD_SPAWN
|
||||
_cleanup_close_ int pidfd = -EBADF;
|
||||
|
||||
r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
|
||||
@@ -2101,15 +2100,18 @@ int posix_spawn_wrapper(
|
||||
|
||||
r = pidfd_spawn(&pidfd, path, NULL, &attr, argv, envp);
|
||||
}
|
||||
if (r != 0)
|
||||
if (r == 0) {
|
||||
r = pidref_set_pidfd_consume(ret_pidref, TAKE_FD(pidfd));
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP);
|
||||
}
|
||||
if (!ERRNO_IS_NOT_SUPPORTED(r))
|
||||
return -r;
|
||||
|
||||
r = pidref_set_pidfd_consume(ret_pidref, TAKE_FD(pidfd));
|
||||
if (r < 0)
|
||||
return r;
|
||||
/* pidfd_spawn unavailable (libc or kernel missing) — fall back to plain posix_spawn. */
|
||||
|
||||
return FLAGS_SET(flags, POSIX_SPAWN_SETCGROUP);
|
||||
#else
|
||||
pid_t pid;
|
||||
|
||||
r = posix_spawn(&pid, path, NULL, &attr, argv, envp);
|
||||
@@ -2121,7 +2123,6 @@ int posix_spawn_wrapper(
|
||||
return r;
|
||||
|
||||
return 0; /* We did not use CLONE_INTO_CGROUP so return 0, the caller will have to move the child */
|
||||
#endif
|
||||
}
|
||||
|
||||
int proc_dir_open(DIR **ret) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "conf-parser.h"
|
||||
#include "coredump-config.h"
|
||||
#include "elf-util.h"
|
||||
#include "format-util.h"
|
||||
#include "journal-def.h"
|
||||
#include "log.h"
|
||||
@@ -45,12 +46,10 @@ int coredump_parse_config(CoredumpConfig *config) {
|
||||
config->journal_size_max = JOURNAL_SIZE_MAX;
|
||||
}
|
||||
|
||||
#if !HAVE_DWFL_SET_SYSROOT
|
||||
if (config->enter_namespace) {
|
||||
if (config->enter_namespace && !dlopen_dw_has_dwfl_set_sysroot()) {
|
||||
log_warning("EnterNamespace= is enabled but libdw does not support dwfl_set_sysroot(), disabling.");
|
||||
config->enter_namespace = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
log_debug("Selected storage '%s'.", coredump_storage_to_string(config->storage));
|
||||
log_debug("Selected compression %s.", yes_no(config->compress));
|
||||
|
||||
@@ -468,7 +468,9 @@ static int maybe_remove_external_coredump(
|
||||
}
|
||||
|
||||
static int acquire_pid_mount_tree_fd(const CoredumpConfig *config, CoredumpContext *context) {
|
||||
#if HAVE_DWFL_SET_SYSROOT
|
||||
if (!dlopen_dw_has_dwfl_set_sysroot())
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "dwfl_set_sysroot() is not supported.");
|
||||
|
||||
_cleanup_close_ int mntns_fd = -EBADF, root_fd = -EBADF, fd = -EBADF;
|
||||
_cleanup_close_pair_ int pair[2] = EBADF_PAIR;
|
||||
int r;
|
||||
@@ -533,10 +535,6 @@ static int acquire_pid_mount_tree_fd(const CoredumpConfig *config, CoredumpConte
|
||||
|
||||
context->mount_tree_fd = TAKE_FD(fd);
|
||||
return 0;
|
||||
#else
|
||||
/* Don't bother preparing environment if we can't pass it to libdwfl. */
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "dwfl_set_sysroot() is not supported.");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int attach_mount_tree(const CoredumpConfig *config, CoredumpContext *context) {
|
||||
|
||||
@@ -608,7 +608,6 @@ static int parse_one_option(const char *option) {
|
||||
log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
|
||||
|
||||
} else if ((val = startswith(option, "link-volume-key="))) {
|
||||
#if HAVE_CRYPT_SET_KEYRING_TO_LINK
|
||||
_cleanup_free_ char *keyring = NULL, *key_type = NULL, *key_description = NULL;
|
||||
const char *sep;
|
||||
|
||||
@@ -657,9 +656,6 @@ static int parse_one_option(const char *option) {
|
||||
free_and_replace(arg_link_keyring, keyring);
|
||||
free_and_replace(arg_link_key_type, key_type);
|
||||
free_and_replace(arg_link_key_description, key_description);
|
||||
#else
|
||||
log_error("Build lacks libcryptsetup support for linking volume keys in user specified kernel keyrings upon device activation, ignoring: %s", option);
|
||||
#endif
|
||||
} else if ((val = startswith(option, "fixate-volume-key="))) {
|
||||
r = free_and_strdup(&arg_fixate_volume_key, val);
|
||||
if (r < 0)
|
||||
@@ -2688,14 +2684,14 @@ static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata)
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", sym_crypt_get_device_name(cd));
|
||||
|
||||
/* since cryptsetup 2.7.0 (Jan 2024) */
|
||||
#if HAVE_CRYPT_SET_KEYRING_TO_LINK
|
||||
/* since cryptsetup 2.7.0 (Jan 2024) */
|
||||
if (arg_link_key_description) {
|
||||
r = sym_crypt_set_keyring_to_link(cd, arg_link_key_description, NULL, arg_link_key_type, arg_link_keyring);
|
||||
if (r < 0)
|
||||
if (r == -ENOSYS)
|
||||
log_warning("Loaded libcryptsetup does not support linking volume keys in user specified kernel keyrings upon device activation, ignoring.");
|
||||
else if (r < 0)
|
||||
log_warning_errno(r, "Failed to set keyring or key description to link volume key in, ignoring: %m");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (arg_header) {
|
||||
r = sym_crypt_set_data_device(cd, source);
|
||||
|
||||
@@ -3,15 +3,15 @@
|
||||
|
||||
#include_next <stdio.h>
|
||||
|
||||
#if !HAVE_RENAMEAT2
|
||||
#ifndef RENAME_NOREPLACE
|
||||
# define RENAME_NOREPLACE (1 << 0)
|
||||
# define RENAME_EXCHANGE (1 << 1)
|
||||
# define RENAME_WHITEOUT (1 << 2)
|
||||
|
||||
int missing_renameat2(int __oldfd, const char *__old, int __newfd, const char *__new, unsigned __flags);
|
||||
# define renameat2 missing_renameat2
|
||||
#endif
|
||||
|
||||
int renameat2_shim(int __oldfd, const char *__old, int __newfd, const char *__new, unsigned __flags);
|
||||
#define renameat2 renameat2_shim
|
||||
|
||||
/* When a stream is opened read-only under glibc, fputs() and friends fail with EBADF. However, they
|
||||
* succeed under musl. We rely on the glibc behavior in the code base. The following _check_writable()
|
||||
* functions first check if the passed stream is writable, and refuse to write with EBADF if not. */
|
||||
|
||||
@@ -27,7 +27,5 @@
|
||||
|
||||
/* Defined since glibc-2.42.
|
||||
* Supported since kernel v5.6 (fddb5d430ad9fa91b49b1d34d0202ffe2fa0e179). */
|
||||
#if !HAVE_OPENAT2
|
||||
int missing_openat2(int dfd, const char *filename, const struct open_how *how, size_t usize);
|
||||
# define openat2 missing_openat2
|
||||
#endif
|
||||
int openat2_shim(int dfd, const char *filename, const struct open_how *how, size_t usize);
|
||||
#define openat2 openat2_shim
|
||||
|
||||
@@ -51,10 +51,8 @@ int __clone2(int (*fn)(void *), void *stack_base, size_t stack_size, int flags,
|
||||
|
||||
/* Defined since glibc-2.41.
|
||||
* Supported since kernel 3.14 (e6cfc0295c7d51b008999a8b13a44fb43f8685ea). */
|
||||
#if !HAVE_SCHED_SETATTR
|
||||
int missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned flags);
|
||||
# define sched_setattr missing_sched_setattr
|
||||
#endif
|
||||
int sched_setattr_shim(pid_t pid, struct sched_attr *attr, unsigned flags);
|
||||
#define sched_setattr sched_setattr_shim
|
||||
|
||||
/* f0e1a0643a59bf1f922fa209cec86a170b784f3f (6.12),
|
||||
* defined in sched.h in glibc since glibc-2.41. */
|
||||
|
||||
@@ -3,7 +3,5 @@
|
||||
|
||||
#include_next <signal.h> /* IWYU pragma: export */
|
||||
|
||||
#if !HAVE_RT_TGSIGQUEUEINFO
|
||||
int missing_rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *info);
|
||||
# define rt_tgsigqueueinfo missing_rt_tgsigqueueinfo
|
||||
#endif
|
||||
int rt_tgsigqueueinfo_shim(pid_t tgid, pid_t tid, int sig, siginfo_t *info);
|
||||
#define rt_tgsigqueueinfo rt_tgsigqueueinfo_shim
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include_next <spawn.h> /* IWYU pragma: export */
|
||||
|
||||
/* pidfd_spawn() and posix_spawnattr_setcgroup_np() were added in glibc 2.39. Redirect to shims that
|
||||
* return ENOSYS at runtime when the libc symbols aren't available, so callers don't need to worry
|
||||
* about the libc version. */
|
||||
int pidfd_spawn_shim(pid_t *restrict pidfd, const char *restrict path,
|
||||
const posix_spawn_file_actions_t *restrict file_actions,
|
||||
const posix_spawnattr_t *restrict attrp,
|
||||
char *const argv[restrict], char *const envp[restrict]);
|
||||
#define pidfd_spawn pidfd_spawn_shim
|
||||
|
||||
int posix_spawnattr_setcgroup_np_shim(posix_spawnattr_t *attr, int cgroup);
|
||||
#define posix_spawnattr_setcgroup_np posix_spawnattr_setcgroup_np_shim
|
||||
|
||||
/* Defined in <spawn.h> since glibc 2.39. */
|
||||
#ifndef POSIX_SPAWN_SETCGROUP
|
||||
# define POSIX_SPAWN_SETCGROUP 0x100
|
||||
#endif
|
||||
@@ -5,7 +5,5 @@
|
||||
#include <stddef.h>
|
||||
|
||||
/* Supported since kernel v3.18 (749730ce42a2121e1c88350d69478bff3994b10a). */
|
||||
#if !HAVE_BPF
|
||||
int missing_bpf(int cmd, union bpf_attr *attr, size_t size);
|
||||
# define bpf missing_bpf
|
||||
#endif
|
||||
int bpf_shim(int cmd, union bpf_attr *attr, size_t size);
|
||||
#define bpf bpf_shim
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include_next <sys/epoll.h> /* IWYU pragma: export */
|
||||
|
||||
/* epoll_pwait2() was added to glibc 2.35. Redirect to a shim that sets errno=ENOSYS at runtime when
|
||||
* the libc symbol isn't available, so callers don't need to worry about the libc version. */
|
||||
int epoll_pwait2_shim(int fd, struct epoll_event *events, int maxevents,
|
||||
const struct timespec *timeout, const sigset_t *sigmask);
|
||||
#define epoll_pwait2 epoll_pwait2_shim
|
||||
@@ -3,12 +3,8 @@
|
||||
|
||||
#include <linux/ioprio.h> /* IWYU pragma: export */
|
||||
|
||||
#if !HAVE_IOPRIO_GET
|
||||
int missing_ioprio_get(int which, int who);
|
||||
# define ioprio_get missing_ioprio_get
|
||||
#endif
|
||||
int ioprio_get_shim(int which, int who);
|
||||
#define ioprio_get ioprio_get_shim
|
||||
|
||||
#if !HAVE_IOPRIO_SET
|
||||
int missing_ioprio_set(int which, int who, int ioprio);
|
||||
# define ioprio_set missing_ioprio_set
|
||||
#endif
|
||||
int ioprio_set_shim(int which, int who, int ioprio);
|
||||
#define ioprio_set ioprio_set_shim
|
||||
|
||||
@@ -5,7 +5,5 @@
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Supported since kernel v3.5 (d97b46a64674a267bc41c9e16132ee2a98c3347d). */
|
||||
#if !HAVE_KCMP
|
||||
int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2);
|
||||
# define kcmp missing_kcmp
|
||||
#endif
|
||||
int kcmp_shim(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2);
|
||||
#define kcmp kcmp_shim
|
||||
|
||||
@@ -6,11 +6,9 @@
|
||||
|
||||
/* Supported since kernel v3.17 (cb1052581e2bddd6096544f3f944f4e7fdad4c4f).
|
||||
* Not available on all architectures. */
|
||||
#if HAVE_KEXEC_FILE_LOAD || defined __NR_kexec_file_load
|
||||
# if !HAVE_KEXEC_FILE_LOAD
|
||||
int missing_kexec_file_load(int kernel_fd, int initrd_fd, unsigned long cmdline_len, const char *cmdline, unsigned long flags);
|
||||
# define kexec_file_load missing_kexec_file_load
|
||||
# endif
|
||||
#ifdef __NR_kexec_file_load
|
||||
int kexec_file_load_shim(int kernel_fd, int initrd_fd, unsigned long cmdline_len, const char *cmdline, unsigned long flags);
|
||||
# define kexec_file_load kexec_file_load_shim
|
||||
# define HAVE_KEXEC_FILE_LOAD_SYSCALL 1
|
||||
#else
|
||||
# define HAVE_KEXEC_FILE_LOAD_SYSCALL 0
|
||||
|
||||
@@ -4,17 +4,11 @@
|
||||
#include <linux/keyctl.h> /* IWYU pragma: export */
|
||||
#include <stddef.h>
|
||||
|
||||
#if !HAVE_KEYCTL
|
||||
long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
|
||||
# define keyctl missing_keyctl
|
||||
#endif
|
||||
long keyctl_shim(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5);
|
||||
#define keyctl keyctl_shim
|
||||
|
||||
#if !HAVE_ADD_KEY
|
||||
key_serial_t missing_add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid);
|
||||
# define add_key missing_add_key
|
||||
#endif
|
||||
key_serial_t add_key_shim(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid);
|
||||
#define add_key add_key_shim
|
||||
|
||||
#if !HAVE_REQUEST_KEY
|
||||
key_serial_t missing_request_key(const char *type, const char *description, const char *callout_info, key_serial_t destringid);
|
||||
# define request_key missing_request_key
|
||||
#endif
|
||||
key_serial_t request_key_shim(const char *type, const char *description, const char *callout_info, key_serial_t destringid);
|
||||
#define request_key request_key_shim
|
||||
|
||||
@@ -3,12 +3,8 @@
|
||||
|
||||
#include <linux/mempolicy.h> /* IWYU pragma: export */
|
||||
|
||||
#if !HAVE_SET_MEMPOLICY
|
||||
int missing_set_mempolicy(int mode, const unsigned long *nodemask, unsigned long maxnode);
|
||||
# define set_mempolicy missing_set_mempolicy
|
||||
#endif
|
||||
int set_mempolicy_shim(int mode, const unsigned long *nodemask, unsigned long maxnode);
|
||||
#define set_mempolicy set_mempolicy_shim
|
||||
|
||||
#if !HAVE_GET_MEMPOLICY
|
||||
int missing_get_mempolicy(int *mode, unsigned long *nodemask, unsigned long maxnode, void *addr, unsigned long flags);
|
||||
# define get_mempolicy missing_get_mempolicy
|
||||
#endif
|
||||
int get_mempolicy_shim(int *mode, unsigned long *nodemask, unsigned long maxnode, void *addr, unsigned long flags);
|
||||
#define get_mempolicy get_mempolicy_shim
|
||||
|
||||
@@ -39,56 +39,36 @@ extern int umount2(const char *__special_file, int __flags);
|
||||
/* Open the filesystem referenced by FS_NAME so it can be configured for mounting. */
|
||||
/* Defined since glibc-2.36.
|
||||
* Supported since kernel v5.2 (24dcb3d90a1f67fe08c68a004af37df059d74005). */
|
||||
#if HAVE_FSOPEN
|
||||
extern int fsopen(const char *__fs_name, unsigned int __flags);
|
||||
#else
|
||||
int missing_fsopen(const char *fsname, unsigned flags);
|
||||
# define fsopen missing_fsopen
|
||||
#endif
|
||||
int fsopen_shim(const char *fsname, unsigned flags);
|
||||
#define fsopen fsopen_shim
|
||||
|
||||
/* Create a mount representation for the FD created by fsopen using
|
||||
FLAGS with ATTR_FLAGS describing how the mount is to be performed. */
|
||||
/* Defined since glibc-2.36.
|
||||
* Supported since kernel v5.2 (93766fbd2696c2c4453dd8e1070977e9cd4e6b6d). */
|
||||
#if HAVE_FSMOUNT
|
||||
extern int fsmount(int __fd, unsigned int __flags, unsigned int __ms_flags);
|
||||
#else
|
||||
int missing_fsmount(int fd, unsigned flags, unsigned ms_flags);
|
||||
# define fsmount missing_fsmount
|
||||
#endif
|
||||
int fsmount_shim(int fd, unsigned flags, unsigned ms_flags);
|
||||
#define fsmount fsmount_shim
|
||||
|
||||
/* Add the mounted FROM_DFD referenced by FROM_PATHNAME filesystem returned
|
||||
by fsmount in the hierarchy in the place TO_DFD reference by TO_PATHNAME
|
||||
using FLAGS. */
|
||||
/* Defined since glibc-2.36.
|
||||
* Supported since kernel v5.2 (2db154b3ea8e14b04fee23e3fdfd5e9d17fbc6ae). */
|
||||
#if HAVE_MOVE_MOUNT
|
||||
extern int move_mount(int __from_dfd, const char *__from_pathname, int __to_dfd, const char *__to_pathname, unsigned int flags);
|
||||
#else
|
||||
int missing_move_mount(int from_dfd, const char *from_pathname, int to_dfd, const char *to_pathname, unsigned flags);
|
||||
# define move_mount missing_move_mount
|
||||
#endif
|
||||
int move_mount_shim(int from_dfd, const char *from_pathname, int to_dfd, const char *to_pathname, unsigned flags);
|
||||
#define move_mount move_mount_shim
|
||||
|
||||
/* Set parameters and trigger CMD action on the FD context. KEY, VALUE,
|
||||
and AUX are used depending ng of the CMD. */
|
||||
/* Defined since glibc-2.36.
|
||||
* Supported since kernel v5.2 (ecdab150fddb42fe6a739335257949220033b782). */
|
||||
#if HAVE_FSCONFIG
|
||||
extern int fsconfig(int __fd, unsigned int __cmd, const char *__key, const void *__value, int __aux);
|
||||
#else
|
||||
int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux);
|
||||
# define fsconfig missing_fsconfig
|
||||
#endif
|
||||
int fsconfig_shim(int fd, unsigned cmd, const char *key, const void *value, int aux);
|
||||
#define fsconfig fsconfig_shim
|
||||
|
||||
/* Open the mount point FILENAME in directory DFD using FLAGS. */
|
||||
/* Defined since glibc-2.36.
|
||||
* Supported since kernel v5.2 (a07b20004793d8926f78d63eb5980559f7813404). */
|
||||
#if HAVE_OPEN_TREE
|
||||
extern int open_tree(int __dfd, const char *__filename, unsigned int __flags);
|
||||
#else
|
||||
int missing_open_tree(int dfd, const char *filename, unsigned flags);
|
||||
# define open_tree missing_open_tree
|
||||
#endif
|
||||
int open_tree_shim(int dfd, const char *filename, unsigned flags);
|
||||
#define open_tree open_tree_shim
|
||||
|
||||
/* Change the mount properties of the mount or an entire mount tree. If
|
||||
PATH is a relative pathname, then it is interpreted relative to the
|
||||
@@ -97,18 +77,10 @@ int missing_open_tree(int dfd, const char *filename, unsigned flags);
|
||||
working directory of the calling process. */
|
||||
/* Defined since glibc-2.36.
|
||||
* Supported since kernel v5.12 (2a1867219c7b27f928e2545782b86daaf9ad50bd). */
|
||||
#if HAVE_MOUNT_SETATTR
|
||||
extern int mount_setattr(int __dfd, const char *__path, unsigned int __flags, struct mount_attr *__uattr, size_t __usize);
|
||||
#else
|
||||
int missing_mount_setattr(int dfd, const char *path, unsigned flags, struct mount_attr *attr, size_t size);
|
||||
# define mount_setattr missing_mount_setattr
|
||||
#endif
|
||||
int mount_setattr_shim(int dfd, const char *path, unsigned flags, struct mount_attr *attr, size_t size);
|
||||
#define mount_setattr mount_setattr_shim
|
||||
|
||||
/* Not defined in glibc yet as of glibc-2.41.
|
||||
* Supported since kernel v6.15 (c4a16820d90199409c9bf01c4f794e1e9e8d8fd8). */
|
||||
#if HAVE_OPEN_TREE_ATTR
|
||||
extern int open_tree_attr(int __dfd, const char *__filename, unsigned int __flags, struct mount_attr *__uattr, size_t __usize);
|
||||
#else
|
||||
int missing_open_tree_attr(int dfd, const char *filename, unsigned int flags, struct mount_attr *attr, size_t size);
|
||||
# define open_tree_attr missing_open_tree_attr
|
||||
#endif
|
||||
int open_tree_attr_shim(int dfd, const char *filename, unsigned int flags, struct mount_attr *attr, size_t size);
|
||||
#define open_tree_attr open_tree_attr_shim
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
/* since glibc-2.36 */
|
||||
#if HAVE_PIDFD_OPEN
|
||||
#include <features.h>
|
||||
|
||||
/* since glibc-2.36. Only descend into the next <sys/pidfd.h> on glibc — musl ships no such header,
|
||||
* and musl-gcc's -idirafter /usr/include would otherwise pull in glibc's copy (which depends on
|
||||
* __THROW and other glibc-isms) from the fallback path. */
|
||||
#if defined(__GLIBC__) && __has_include_next(<sys/pidfd.h>)
|
||||
#include_next <sys/pidfd.h> /* IWYU pragma: export */
|
||||
#endif
|
||||
|
||||
@@ -12,17 +16,13 @@
|
||||
|
||||
/* Defined since glibc-2.36.
|
||||
* Supported since kernel v5.3 (7615d9e1780e26e0178c93c55b73309a5dc093d7). */
|
||||
#if !HAVE_PIDFD_OPEN
|
||||
int missing_pidfd_open(pid_t pid, unsigned flags);
|
||||
# define pidfd_open missing_pidfd_open
|
||||
#endif
|
||||
int pidfd_open_shim(pid_t pid, unsigned flags);
|
||||
#define pidfd_open pidfd_open_shim
|
||||
|
||||
/* Defined since glibc-2.36.
|
||||
* Supported since kernel v5.1 (3eb39f47934f9d5a3027fe00d906a45fe3a15fad). */
|
||||
#if !HAVE_PIDFD_SEND_SIGNAL
|
||||
int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags);
|
||||
# define pidfd_send_signal missing_pidfd_send_signal
|
||||
#endif
|
||||
int pidfd_send_signal_shim(int fd, int sig, siginfo_t *info, unsigned flags);
|
||||
#define pidfd_send_signal pidfd_send_signal_shim
|
||||
|
||||
/* since glibc-2.41 */
|
||||
#ifndef PIDFS_IOCTL_MAGIC
|
||||
|
||||
@@ -4,7 +4,5 @@
|
||||
#include_next <sys/quota.h> /* IWYU pragma: export */
|
||||
|
||||
/* Supported since kernel v5.14 (64c2c2c62f92339b176ea24403d8db16db36f9e6). */
|
||||
#if !HAVE_QUOTACTL_FD
|
||||
int missing_quotactl_fd(int fd, int cmd, int id, void *addr);
|
||||
# define quotactl_fd missing_quotactl_fd
|
||||
#endif
|
||||
int quotactl_fd_shim(int fd, int cmd, int id, void *addr);
|
||||
#define quotactl_fd quotactl_fd_shim
|
||||
|
||||
@@ -4,7 +4,5 @@
|
||||
#include_next <sys/stat.h> /* IWYU pragma: export */
|
||||
|
||||
/* Supported since kernel v6.6 (78252deb023cf0879256fcfbafe37022c390762b). */
|
||||
#if !HAVE_FCHMODAT2
|
||||
int missing_fchmodat2(int dirfd, const char *path, mode_t mode, int flags);
|
||||
# define fchmodat2 missing_fchmodat2
|
||||
#endif
|
||||
int fchmodat2_shim(int dirfd, const char *path, mode_t mode, int flags);
|
||||
#define fchmodat2 fchmodat2_shim
|
||||
|
||||
@@ -8,13 +8,9 @@
|
||||
#include_next <sys/xattr.h> /* IWYU pragma: export */
|
||||
|
||||
/* Supported since kernel v6.13 (6140be90ec70c39fa844741ca3cc807dd0866394). */
|
||||
#if !HAVE_SETXATTRAT
|
||||
int missing_setxattrat(int fd, const char *path, int at_flags, const char *name, const struct xattr_args *args, size_t size);
|
||||
# define setxattrat missing_setxattrat
|
||||
#endif
|
||||
int setxattrat_shim(int fd, const char *path, int at_flags, const char *name, const struct xattr_args *args, size_t size);
|
||||
#define setxattrat setxattrat_shim
|
||||
|
||||
/* Supported since kernel v6.13 (6140be90ec70c39fa844741ca3cc807dd0866394). */
|
||||
#if !HAVE_REMOVEXATTRAT
|
||||
int missing_removexattrat(int fd, const char *path, int at_flags, const char *name);
|
||||
# define removexattrat missing_removexattrat
|
||||
#endif
|
||||
int removexattrat_shim(int fd, const char *path, int at_flags, const char *name);
|
||||
#define removexattrat removexattrat_shim
|
||||
|
||||
@@ -3,7 +3,5 @@
|
||||
|
||||
#include_next <unistd.h> /* IWYU pragma: export */
|
||||
|
||||
#if !HAVE_PIVOT_ROOT
|
||||
int missing_pivot_root(const char *new_root, const char *put_old);
|
||||
# define pivot_root missing_pivot_root
|
||||
#endif
|
||||
int pivot_root_shim(const char *new_root, const char *put_old);
|
||||
#define pivot_root pivot_root_shim
|
||||
|
||||
+6
-7
@@ -1,11 +1,10 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/bpf.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_BPF
|
||||
int missing_bpf(int cmd, union bpf_attr *attr, size_t size) {
|
||||
return syscall(__NR_bpf, cmd, attr, size);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
DEFINE_SYSCALL_SHIM(bpf, int,
|
||||
int, cmd,
|
||||
union bpf_attr *, attr,
|
||||
size_t, size)
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#include "libc-shim.h"
|
||||
|
||||
DEFINE_LIBC_ERRNO_SHIM(epoll_pwait2, int,
|
||||
int, fd,
|
||||
struct epoll_event *, events,
|
||||
int, maxevents,
|
||||
const struct timespec *, timeout,
|
||||
const sigset_t *, sigmask)
|
||||
+7
-7
@@ -1,11 +1,11 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_OPENAT2
|
||||
int missing_openat2(int dfd, const char *filename, const struct open_how *how, size_t usize) {
|
||||
return syscall(__NR_openat2, dfd, filename, how, usize);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
DEFINE_SYSCALL_SHIM(openat2, int,
|
||||
int, dfd,
|
||||
const char *, filename,
|
||||
const struct open_how *, how,
|
||||
size_t, usize)
|
||||
|
||||
+9
-12
@@ -1,17 +1,14 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/ioprio.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_IOPRIO_GET
|
||||
int missing_ioprio_get(int which, int who) {
|
||||
return syscall(__NR_ioprio_get, which, who);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
#if !HAVE_IOPRIO_SET
|
||||
int missing_ioprio_set(int which, int who, int ioprio) {
|
||||
return syscall(__NR_ioprio_set, which, who, ioprio);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(ioprio_get, int,
|
||||
int, which,
|
||||
int, who)
|
||||
|
||||
DEFINE_SYSCALL_SHIM(ioprio_set, int,
|
||||
int, which,
|
||||
int, who,
|
||||
int, ioprio)
|
||||
|
||||
+8
-7
@@ -1,11 +1,12 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/kcmp.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_KCMP
|
||||
int missing_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) {
|
||||
return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
DEFINE_SYSCALL_SHIM(kcmp, int,
|
||||
pid_t, pid1,
|
||||
pid_t, pid2,
|
||||
int, type,
|
||||
unsigned long, idx1,
|
||||
unsigned long, idx2)
|
||||
|
||||
+9
-6
@@ -1,11 +1,14 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/kexec.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_KEXEC_FILE_LOAD && defined __NR_kexec_file_load
|
||||
int missing_kexec_file_load(int kernel_fd, int initrd_fd, unsigned long cmdline_len, const char *cmdline, unsigned long flags) {
|
||||
return syscall(__NR_kexec_file_load, kernel_fd, initrd_fd, cmdline_len, cmdline, flags);
|
||||
}
|
||||
#include "libc-shim.h"
|
||||
|
||||
#ifdef __NR_kexec_file_load
|
||||
DEFINE_SYSCALL_SHIM(kexec_file_load, int,
|
||||
int, kernel_fd,
|
||||
int, initrd_fd,
|
||||
unsigned long, cmdline_len,
|
||||
const char *, cmdline,
|
||||
unsigned long, flags)
|
||||
#endif
|
||||
|
||||
+19
-17
@@ -1,23 +1,25 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/keyctl.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_KEYCTL
|
||||
long missing_keyctl(int cmd, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5) {
|
||||
return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
#if !HAVE_ADD_KEY
|
||||
key_serial_t missing_add_key(const char *type, const char *description, const void *payload, size_t plen, key_serial_t ringid) {
|
||||
return syscall(__NR_add_key, type, description, payload, plen, ringid);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(keyctl, long,
|
||||
int, cmd,
|
||||
unsigned long, arg2,
|
||||
unsigned long, arg3,
|
||||
unsigned long, arg4,
|
||||
unsigned long, arg5)
|
||||
|
||||
#if !HAVE_REQUEST_KEY
|
||||
key_serial_t missing_request_key(const char *type, const char *description, const char *callout_info, key_serial_t destringid) {
|
||||
return syscall(__NR_request_key, type, description, callout_info, destringid);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(add_key, key_serial_t,
|
||||
const char *, type,
|
||||
const char *, description,
|
||||
const void *, payload,
|
||||
size_t, plen,
|
||||
key_serial_t, ringid)
|
||||
|
||||
DEFINE_SYSCALL_SHIM(request_key, key_serial_t,
|
||||
const char *, type,
|
||||
const char *, description,
|
||||
const char *, callout_info,
|
||||
key_serial_t, destringid)
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <errno.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* Each parameter is passed as a flat (type, name) pair: type1, name1, type2, name2, ... The
|
||||
* _SHIM_DECL/_SHIM_NAME macros consume two args at a time and emit either "type name" pairs (for
|
||||
* the function declarator) or just the names (for forwarding). _SHIM_PAIRS counts the number of
|
||||
* pairs by indexing into a table that increments every two positions. */
|
||||
#define _SHIM_CAT(a, b) _SHIM_CAT_(a, b)
|
||||
#define _SHIM_CAT_(a, b) a##b
|
||||
|
||||
#define _SHIM_NTH(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
|
||||
#define _SHIM_PAIRS(...) _SHIM_NTH(__VA_ARGS__, 8, 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0)
|
||||
|
||||
#define _SHIM_DECL_1(t, n) t n
|
||||
#define _SHIM_DECL_2(t, n, ...) t n, _SHIM_DECL_1(__VA_ARGS__)
|
||||
#define _SHIM_DECL_3(t, n, ...) t n, _SHIM_DECL_2(__VA_ARGS__)
|
||||
#define _SHIM_DECL_4(t, n, ...) t n, _SHIM_DECL_3(__VA_ARGS__)
|
||||
#define _SHIM_DECL_5(t, n, ...) t n, _SHIM_DECL_4(__VA_ARGS__)
|
||||
#define _SHIM_DECL_6(t, n, ...) t n, _SHIM_DECL_5(__VA_ARGS__)
|
||||
#define _SHIM_DECL_7(t, n, ...) t n, _SHIM_DECL_6(__VA_ARGS__)
|
||||
#define _SHIM_DECL_8(t, n, ...) t n, _SHIM_DECL_7(__VA_ARGS__)
|
||||
#define _SHIM_DECL(...) _SHIM_CAT(_SHIM_DECL_, _SHIM_PAIRS(__VA_ARGS__))(__VA_ARGS__)
|
||||
|
||||
#define _SHIM_NAME_1(t, n) n
|
||||
#define _SHIM_NAME_2(t, n, ...) n, _SHIM_NAME_1(__VA_ARGS__)
|
||||
#define _SHIM_NAME_3(t, n, ...) n, _SHIM_NAME_2(__VA_ARGS__)
|
||||
#define _SHIM_NAME_4(t, n, ...) n, _SHIM_NAME_3(__VA_ARGS__)
|
||||
#define _SHIM_NAME_5(t, n, ...) n, _SHIM_NAME_4(__VA_ARGS__)
|
||||
#define _SHIM_NAME_6(t, n, ...) n, _SHIM_NAME_5(__VA_ARGS__)
|
||||
#define _SHIM_NAME_7(t, n, ...) n, _SHIM_NAME_6(__VA_ARGS__)
|
||||
#define _SHIM_NAME_8(t, n, ...) n, _SHIM_NAME_7(__VA_ARGS__)
|
||||
#define _SHIM_NAME(...) _SHIM_CAT(_SHIM_NAME_, _SHIM_PAIRS(__VA_ARGS__))(__VA_ARGS__)
|
||||
|
||||
/* Defines a wrapper that calls the libc symbol if available at runtime, or falls back to the
|
||||
* corresponding direct syscall otherwise. The libc symbol is redeclared as a weak reference so the
|
||||
* binary still loads on libc versions that don't provide it. Each parameter is passed as type,
|
||||
* name pairs (flat).
|
||||
*
|
||||
* The weak reference is bound to the libc symbol via an __asm__("label") rename so that the bare
|
||||
* libc identifier never appears as a C token. This matters because override/musl headers
|
||||
* sometimes #define the libc name to redirect it to the _shim variant — without the rename the
|
||||
* caller would have to #undef each name before invoking the macro. # and ## operators don't
|
||||
* macro-expand their operands, so the parameter "func" stays a literal token everywhere. */
|
||||
#define DEFINE_SYSCALL_SHIM(func, ret, ...) \
|
||||
extern typeof(func##_shim) func##_libc_weak __asm__(#func) __attribute__((__weak__)); \
|
||||
ret func##_shim(_SHIM_DECL(__VA_ARGS__)) { \
|
||||
if (func##_libc_weak) \
|
||||
return func##_libc_weak(_SHIM_NAME(__VA_ARGS__)); \
|
||||
return syscall(__NR_##func, _SHIM_NAME(__VA_ARGS__)); \
|
||||
}
|
||||
|
||||
/* Like DEFINE_SYSCALL_SHIM but for libc helpers that have no corresponding syscall and report errors
|
||||
* by returning the positive errno value directly (posix_spawn-family convention). If the libc symbol
|
||||
* is missing at runtime, ENOSYS is returned. */
|
||||
#define DEFINE_LIBC_SHIM(func, ret, ...) \
|
||||
extern typeof(func##_shim) func##_libc_weak __asm__(#func) __attribute__((__weak__)); \
|
||||
ret func##_shim(_SHIM_DECL(__VA_ARGS__)) { \
|
||||
if (func##_libc_weak) \
|
||||
return func##_libc_weak(_SHIM_NAME(__VA_ARGS__)); \
|
||||
return ENOSYS; \
|
||||
}
|
||||
|
||||
/* Like DEFINE_LIBC_SHIM but for libc helpers that report errors via errno + -1 return value. If the
|
||||
* libc symbol is missing at runtime, errno is set to ENOSYS and -1 is returned. */
|
||||
#define DEFINE_LIBC_ERRNO_SHIM(func, ret, ...) \
|
||||
extern typeof(func##_shim) func##_libc_weak __asm__(#func) __attribute__((__weak__)); \
|
||||
ret func##_shim(_SHIM_DECL(__VA_ARGS__)) { \
|
||||
if (func##_libc_weak) \
|
||||
return func##_libc_weak(_SHIM_NAME(__VA_ARGS__)); \
|
||||
errno = ENOSYS; \
|
||||
return -1; \
|
||||
}
|
||||
+12
-12
@@ -1,17 +1,17 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/mempolicy.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_SET_MEMPOLICY
|
||||
int missing_set_mempolicy(int mode, const unsigned long *nodemask, unsigned long maxnode) {
|
||||
return syscall(__NR_set_mempolicy, mode, nodemask, maxnode);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
#if !HAVE_GET_MEMPOLICY
|
||||
int missing_get_mempolicy(int *mode, unsigned long *nodemask, unsigned long maxnode, void *addr, unsigned long flags) {
|
||||
return syscall(__NR_get_mempolicy, mode, nodemask, maxnode, addr, flags);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(set_mempolicy, int,
|
||||
int, mode,
|
||||
const unsigned long *, nodemask,
|
||||
unsigned long, maxnode)
|
||||
|
||||
DEFINE_SYSCALL_SHIM(get_mempolicy, int,
|
||||
int *, mode,
|
||||
unsigned long *, nodemask,
|
||||
unsigned long, maxnode,
|
||||
void *, addr,
|
||||
unsigned long, flags)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
libc_wrapper_sources = files(
|
||||
'bpf.c',
|
||||
'epoll.c',
|
||||
'fcntl.c',
|
||||
'ioprio.c',
|
||||
'kcmp.c',
|
||||
@@ -13,6 +14,7 @@ libc_wrapper_sources = files(
|
||||
'quota.c',
|
||||
'sched.c',
|
||||
'signal.c',
|
||||
'spawn.c',
|
||||
'stat.c',
|
||||
'unistd.c',
|
||||
'xattr.c',
|
||||
|
||||
+37
-37
@@ -1,47 +1,47 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/mount.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_FSOPEN
|
||||
int missing_fsopen(const char *fsname, unsigned flags) {
|
||||
return syscall(__NR_fsopen, fsname, flags);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
#if !HAVE_FSMOUNT
|
||||
int missing_fsmount(int fd, unsigned flags, unsigned ms_flags) {
|
||||
return syscall(__NR_fsmount, fd, flags, ms_flags);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(fsopen, int,
|
||||
const char *, fsname,
|
||||
unsigned, flags)
|
||||
|
||||
#if !HAVE_MOVE_MOUNT
|
||||
int missing_move_mount(int from_dfd, const char *from_pathname, int to_dfd, const char *to_pathname, unsigned flags) {
|
||||
return syscall(__NR_move_mount, from_dfd, from_pathname, to_dfd, to_pathname, flags);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(fsmount, int,
|
||||
int, fd,
|
||||
unsigned, flags,
|
||||
unsigned, ms_flags)
|
||||
|
||||
#if !HAVE_FSCONFIG
|
||||
int missing_fsconfig(int fd, unsigned cmd, const char *key, const void *value, int aux) {
|
||||
return syscall(__NR_fsconfig, fd, cmd, key, value, aux);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(move_mount, int,
|
||||
int, from_dfd,
|
||||
const char *, from_pathname,
|
||||
int, to_dfd,
|
||||
const char *, to_pathname,
|
||||
unsigned, flags)
|
||||
|
||||
#if !HAVE_OPEN_TREE
|
||||
int missing_open_tree(int dfd, const char *filename, unsigned flags) {
|
||||
return syscall(__NR_open_tree, dfd, filename, flags);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(fsconfig, int,
|
||||
int, fd,
|
||||
unsigned, cmd,
|
||||
const char *, key,
|
||||
const void *, value,
|
||||
int, aux)
|
||||
|
||||
#if !HAVE_MOUNT_SETATTR
|
||||
int missing_mount_setattr(int dfd, const char *path, unsigned flags, struct mount_attr *attr, size_t size) {
|
||||
return syscall(__NR_mount_setattr, dfd, path, flags, attr, size);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(open_tree, int,
|
||||
int, dfd,
|
||||
const char *, filename,
|
||||
unsigned, flags)
|
||||
|
||||
#if !HAVE_OPEN_TREE_ATTR
|
||||
int missing_open_tree_attr(int dfd, const char *filename, unsigned int flags, struct mount_attr *attr, size_t size) {
|
||||
return syscall(__NR_open_tree_attr, dfd, filename, flags, attr, size);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(mount_setattr, int,
|
||||
int, dfd,
|
||||
const char *, path,
|
||||
unsigned, flags,
|
||||
struct mount_attr *, attr,
|
||||
size_t, size)
|
||||
|
||||
DEFINE_SYSCALL_SHIM(open_tree_attr, int,
|
||||
int, dfd,
|
||||
const char *, filename,
|
||||
unsigned int, flags,
|
||||
struct mount_attr *, attr,
|
||||
size_t, size)
|
||||
|
||||
@@ -3,14 +3,15 @@
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdio_ext.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_RENAMEAT2
|
||||
int missing_renameat2(int __oldfd, const char *__old, int __newfd, const char *__new, unsigned __flags) {
|
||||
return syscall(__NR_renameat2, __oldfd, __old, __newfd, __new, __flags);
|
||||
}
|
||||
#endif
|
||||
#include "../libc-shim.h"
|
||||
|
||||
DEFINE_SYSCALL_SHIM(renameat2, int,
|
||||
int, __oldfd,
|
||||
const char *, __old,
|
||||
int, __newfd,
|
||||
const char *, __new,
|
||||
unsigned, __flags)
|
||||
|
||||
#define DEFINE_PUT(func) \
|
||||
int func##_check_writable(int c, FILE *stream) { \
|
||||
|
||||
+10
-12
@@ -1,17 +1,15 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/pidfd.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_PIDFD_OPEN
|
||||
int missing_pidfd_open(pid_t pid, unsigned flags) {
|
||||
return syscall(__NR_pidfd_open, pid, flags);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
#if !HAVE_PIDFD_SEND_SIGNAL
|
||||
int missing_pidfd_send_signal(int fd, int sig, siginfo_t *info, unsigned flags) {
|
||||
return syscall(__NR_pidfd_send_signal, fd, sig, info, flags);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(pidfd_open, int,
|
||||
pid_t, pid,
|
||||
unsigned, flags)
|
||||
|
||||
DEFINE_SYSCALL_SHIM(pidfd_send_signal, int,
|
||||
int, fd,
|
||||
int, sig,
|
||||
siginfo_t *, info,
|
||||
unsigned, flags)
|
||||
|
||||
+7
-7
@@ -1,11 +1,11 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/quota.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_QUOTACTL_FD
|
||||
int missing_quotactl_fd(int fd, int cmd, int id, void *addr) {
|
||||
return syscall(__NR_quotactl_fd, fd, cmd, id, addr);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
DEFINE_SYSCALL_SHIM(quotactl_fd, int,
|
||||
int, fd,
|
||||
int, cmd,
|
||||
int, id,
|
||||
void *, addr)
|
||||
|
||||
+6
-7
@@ -1,11 +1,10 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sched.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_SCHED_SETATTR
|
||||
int missing_sched_setattr(pid_t pid, struct sched_attr *attr, unsigned flags) {
|
||||
return syscall(__NR_sched_setattr, pid, attr, flags);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
DEFINE_SYSCALL_SHIM(sched_setattr, int,
|
||||
pid_t, pid,
|
||||
struct sched_attr *, attr,
|
||||
unsigned, flags)
|
||||
|
||||
+7
-7
@@ -1,11 +1,11 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_RT_TGSIGQUEUEINFO
|
||||
int missing_rt_tgsigqueueinfo(pid_t tgid, pid_t tid, int sig, siginfo_t *info) {
|
||||
return syscall(__NR_rt_tgsigqueueinfo, tgid, tid, sig, info);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
DEFINE_SYSCALL_SHIM(rt_tgsigqueueinfo, int,
|
||||
pid_t, tgid,
|
||||
pid_t, tid,
|
||||
int, sig,
|
||||
siginfo_t *, info)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <spawn.h>
|
||||
|
||||
#include "libc-shim.h"
|
||||
|
||||
DEFINE_LIBC_SHIM(pidfd_spawn, int,
|
||||
pid_t *restrict, pidfd,
|
||||
const char *restrict, path,
|
||||
const posix_spawn_file_actions_t *restrict, file_actions,
|
||||
const posix_spawnattr_t *restrict, attrp,
|
||||
char *const *restrict, argv,
|
||||
char *const *restrict, envp)
|
||||
|
||||
DEFINE_LIBC_SHIM(posix_spawnattr_setcgroup_np, int,
|
||||
posix_spawnattr_t *, attr,
|
||||
int, cgroup)
|
||||
+7
-7
@@ -1,11 +1,11 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_FCHMODAT2
|
||||
int missing_fchmodat2(int dirfd, const char *path, mode_t mode, int flags) {
|
||||
return syscall(__NR_fchmodat2, dirfd, path, mode, flags);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
DEFINE_SYSCALL_SHIM(fchmodat2, int,
|
||||
int, dirfd,
|
||||
const char *, path,
|
||||
mode_t, mode,
|
||||
int, flags)
|
||||
|
||||
+4
-7
@@ -1,10 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#include "libc-shim.h"
|
||||
|
||||
#if !HAVE_PIVOT_ROOT
|
||||
int missing_pivot_root(const char *new_root, const char *put_old) {
|
||||
return syscall(__NR_pivot_root, new_root, put_old);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(pivot_root, int,
|
||||
const char *, new_root,
|
||||
const char *, put_old)
|
||||
|
||||
+14
-12
@@ -1,17 +1,19 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/xattr.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#if !HAVE_SETXATTRAT
|
||||
int missing_setxattrat(int fd, const char *path, int at_flags, const char *name, const struct xattr_args *args, size_t size) {
|
||||
return syscall(__NR_setxattrat, fd, path, at_flags, name, args, size);
|
||||
}
|
||||
#endif
|
||||
#include "libc-shim.h"
|
||||
|
||||
#if !HAVE_REMOVEXATTRAT
|
||||
int missing_removexattrat(int fd, const char *path, int at_flags, const char *name) {
|
||||
return syscall(__NR_removexattrat, fd, path, at_flags, name);
|
||||
}
|
||||
#endif
|
||||
DEFINE_SYSCALL_SHIM(setxattrat, int,
|
||||
int, fd,
|
||||
const char *, path,
|
||||
int, at_flags,
|
||||
const char *, name,
|
||||
const struct xattr_args *, args,
|
||||
size_t, size)
|
||||
|
||||
DEFINE_SYSCALL_SHIM(removexattrat, int,
|
||||
int, fd,
|
||||
const char *, path,
|
||||
int, at_flags,
|
||||
const char *, name)
|
||||
|
||||
@@ -4629,19 +4629,9 @@ static int epoll_wait_usec(
|
||||
int maxevents,
|
||||
usec_t timeout) {
|
||||
|
||||
int msec;
|
||||
/* A wrapper that uses epoll_pwait2() if available, and falls back to epoll_wait() if not. */
|
||||
|
||||
#if HAVE_EPOLL_PWAIT2
|
||||
static bool epoll_pwait2_absent = false;
|
||||
int r;
|
||||
|
||||
/* epoll_pwait2() was added to Linux 5.11 (2021-02-14) and to glibc in 2.35 (2022-02-03). In contrast
|
||||
* to other syscalls we don't bother with our own fallback syscall wrappers on old libcs, since this
|
||||
* is not that obvious to implement given the libc and kernel definitions differ in the last
|
||||
* argument. Moreover, the only reason to use it is the more accurate timeouts (which is not a
|
||||
* biggie), let's hence rely on glibc's definitions, and fallback to epoll_pwait() when that's
|
||||
* missing. */
|
||||
int r, msec;
|
||||
/* A wrapper that uses epoll_pwait2() if available, and falls back to epoll_wait() if not. */
|
||||
|
||||
if (!epoll_pwait2_absent && timeout != USEC_INFINITY) {
|
||||
r = epoll_pwait2(fd,
|
||||
@@ -4657,7 +4647,6 @@ static int epoll_wait_usec(
|
||||
|
||||
epoll_pwait2_absent = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (timeout == USEC_INFINITY)
|
||||
msec = -1;
|
||||
|
||||
@@ -55,9 +55,15 @@ DLSYM_PROTOTYPE(crypt_resume_by_volume_key) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_set_data_device) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_set_data_offset) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_set_debug_level) = NULL;
|
||||
#if HAVE_CRYPT_SET_KEYRING_TO_LINK
|
||||
DLSYM_PROTOTYPE(crypt_set_keyring_to_link) = NULL;
|
||||
#endif
|
||||
static int missing_crypt_set_keyring_to_link(
|
||||
struct crypt_device *cd,
|
||||
const char *key_description,
|
||||
const char *old_key_description,
|
||||
const char *key_type_desc,
|
||||
const char *keyring_to_link_vk) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
DLSYM_PROTOTYPE(crypt_set_keyring_to_link) = missing_crypt_set_keyring_to_link;
|
||||
DLSYM_PROTOTYPE(crypt_set_log_callback) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_set_metadata_size) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_set_pbkdf_type) = NULL;
|
||||
@@ -67,9 +73,10 @@ DLSYM_PROTOTYPE(crypt_token_external_path) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_token_json_get) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_token_json_set) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_token_max) = NULL;
|
||||
#if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH
|
||||
DLSYM_PROTOTYPE(crypt_token_set_external_path) = NULL;
|
||||
#endif
|
||||
static int missing_crypt_token_set_external_path(const char *path) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
DLSYM_PROTOTYPE(crypt_token_set_external_path) = missing_crypt_token_set_external_path;
|
||||
DLSYM_PROTOTYPE(crypt_token_status) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_volume_key_get) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_volume_key_keyring) = NULL;
|
||||
@@ -318,9 +325,6 @@ int dlopen_cryptsetup(int log_level) {
|
||||
DLSYM_ARG(crypt_set_data_device),
|
||||
DLSYM_ARG(crypt_set_data_offset),
|
||||
DLSYM_ARG(crypt_set_debug_level),
|
||||
#if HAVE_CRYPT_SET_KEYRING_TO_LINK
|
||||
DLSYM_ARG(crypt_set_keyring_to_link),
|
||||
#endif
|
||||
DLSYM_ARG(crypt_set_log_callback),
|
||||
DLSYM_ARG(crypt_set_metadata_size),
|
||||
DLSYM_ARG(crypt_set_pbkdf_type),
|
||||
@@ -330,9 +334,6 @@ int dlopen_cryptsetup(int log_level) {
|
||||
DLSYM_ARG(crypt_token_json_get),
|
||||
DLSYM_ARG(crypt_token_json_set),
|
||||
DLSYM_ARG(crypt_token_max),
|
||||
#if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH
|
||||
DLSYM_ARG(crypt_token_set_external_path),
|
||||
#endif
|
||||
DLSYM_ARG(crypt_token_status),
|
||||
DLSYM_ARG(crypt_volume_key_get),
|
||||
DLSYM_ARG(crypt_volume_key_keyring),
|
||||
@@ -341,6 +342,12 @@ int dlopen_cryptsetup(int log_level) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
/* Optional symbols: present in libcryptsetup 2.7+ only. If unresolved, the prototype keeps its
|
||||
* static initializer pointing at a fallback that returns -ENOSYS, so call sites can invoke the
|
||||
* symbol unconditionally. */
|
||||
DLSYM_OPTIONAL(cryptsetup_dl, crypt_set_keyring_to_link);
|
||||
DLSYM_OPTIONAL(cryptsetup_dl, crypt_token_set_external_path);
|
||||
|
||||
/* Redirect the default logging calls of libcryptsetup to our own logging infra. (Note that
|
||||
* libcryptsetup also maintains per-"struct crypt_device" log functions, which we'll also set
|
||||
* whenever allocating a "struct crypt_device" context. Why set both? To be defensive: maybe some
|
||||
@@ -350,13 +357,11 @@ int dlopen_cryptsetup(int log_level) {
|
||||
|
||||
const char *e = secure_getenv("SYSTEMD_CRYPTSETUP_TOKEN_PATH");
|
||||
if (e) {
|
||||
#if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH
|
||||
r = sym_crypt_token_set_external_path(e);
|
||||
if (r < 0)
|
||||
if (r == -ENOSYS)
|
||||
log_debug("Loaded libcryptsetup does not support setting the external token path, not setting it to '%s'.", e);
|
||||
else if (r < 0)
|
||||
log_debug_errno(r, "Failed to set the libcryptsetup external token path to '%s', ignoring: %m", e);
|
||||
#else
|
||||
log_debug("libcryptsetup version does not support setting the external token path, not setting it to '%s'.", e);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -7,6 +7,19 @@
|
||||
#if HAVE_LIBCRYPTSETUP
|
||||
#include <libcryptsetup.h> /* IWYU pragma: export */
|
||||
|
||||
/* Available since libcryptsetup 2.7. Always redeclare so DLSYM_PROTOTYPE's typeof() resolves on older
|
||||
* headers; suppress the warning when newer libcryptsetup already declares them. */
|
||||
DISABLE_WARNING_REDUNDANT_DECLS;
|
||||
/* NOLINTBEGIN(readability-redundant-declaration) */
|
||||
extern int crypt_set_keyring_to_link(struct crypt_device *cd,
|
||||
const char *key_description,
|
||||
const char *old_key_description,
|
||||
const char *key_type_desc,
|
||||
const char *keyring_to_link_vk);
|
||||
extern int crypt_token_set_external_path(const char *path);
|
||||
/* NOLINTEND(readability-redundant-declaration) */
|
||||
REENABLE_WARNING;
|
||||
|
||||
extern DLSYM_PROTOTYPE(crypt_activate_by_passphrase);
|
||||
extern DLSYM_PROTOTYPE(crypt_activate_by_signed_key);
|
||||
extern DLSYM_PROTOTYPE(crypt_activate_by_token_pin);
|
||||
@@ -43,9 +56,7 @@ extern DLSYM_PROTOTYPE(crypt_resume_by_volume_key);
|
||||
extern DLSYM_PROTOTYPE(crypt_set_data_device);
|
||||
extern DLSYM_PROTOTYPE(crypt_set_data_offset);
|
||||
extern DLSYM_PROTOTYPE(crypt_set_debug_level);
|
||||
#if HAVE_CRYPT_SET_KEYRING_TO_LINK
|
||||
extern DLSYM_PROTOTYPE(crypt_set_keyring_to_link);
|
||||
#endif
|
||||
extern DLSYM_PROTOTYPE(crypt_set_log_callback);
|
||||
extern DLSYM_PROTOTYPE(crypt_set_metadata_size);
|
||||
extern DLSYM_PROTOTYPE(crypt_set_pbkdf_type);
|
||||
@@ -55,9 +66,7 @@ extern DLSYM_PROTOTYPE(crypt_token_external_path);
|
||||
extern DLSYM_PROTOTYPE(crypt_token_json_get);
|
||||
extern DLSYM_PROTOTYPE(crypt_token_json_set);
|
||||
extern DLSYM_PROTOTYPE(crypt_token_max);
|
||||
#if HAVE_CRYPT_TOKEN_SET_EXTERNAL_PATH
|
||||
extern DLSYM_PROTOTYPE(crypt_token_set_external_path);
|
||||
#endif
|
||||
extern DLSYM_PROTOTYPE(crypt_token_status);
|
||||
extern DLSYM_PROTOTYPE(crypt_volume_key_get);
|
||||
extern DLSYM_PROTOTYPE(crypt_volume_key_keyring);
|
||||
|
||||
+25
-12
@@ -56,9 +56,12 @@ static DLSYM_PROTOTYPE(dwfl_begin) = NULL;
|
||||
static DLSYM_PROTOTYPE(dwfl_build_id_find_elf) = NULL;
|
||||
static DLSYM_PROTOTYPE(dwfl_core_file_attach) = NULL;
|
||||
static DLSYM_PROTOTYPE(dwfl_core_file_report) = NULL;
|
||||
#if HAVE_DWFL_SET_SYSROOT
|
||||
/* New in elfutils 0.192. Always redeclare so DLSYM_PROTOTYPE's typeof() resolves on older headers; suppress
|
||||
* the warning when newer libdw already declared it. */
|
||||
DISABLE_WARNING_REDUNDANT_DECLS;
|
||||
extern int dwfl_set_sysroot(Dwfl *dwfl, const char *sysroot); /* NOLINT(readability-redundant-declaration) */
|
||||
REENABLE_WARNING;
|
||||
static DLSYM_PROTOTYPE(dwfl_set_sysroot) = NULL;
|
||||
#endif
|
||||
static DLSYM_PROTOTYPE(dwfl_end) = NULL;
|
||||
static DLSYM_PROTOTYPE(dwfl_errmsg) = NULL;
|
||||
static DLSYM_PROTOTYPE(dwfl_errno) = NULL;
|
||||
@@ -121,9 +124,6 @@ int dlopen_dw(int log_level) {
|
||||
DLSYM_ARG(dwfl_module_getelf),
|
||||
DLSYM_ARG(dwfl_begin),
|
||||
DLSYM_ARG(dwfl_core_file_report),
|
||||
#if HAVE_DWFL_SET_SYSROOT
|
||||
DLSYM_ARG(dwfl_set_sysroot),
|
||||
#endif
|
||||
DLSYM_ARG(dwfl_report_end),
|
||||
DLSYM_ARG(dwfl_getmodules),
|
||||
DLSYM_ARG(dwfl_core_file_attach),
|
||||
@@ -139,6 +139,9 @@ int dlopen_dw(int log_level) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
/* Optional symbol: present in libdw 0.192+. NULL pointer is fine; call sites check at use. */
|
||||
DLSYM_OPTIONAL(dw_dl, dwfl_set_sysroot);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
@@ -146,6 +149,16 @@ int dlopen_dw(int log_level) {
|
||||
#endif
|
||||
}
|
||||
|
||||
bool dlopen_dw_has_dwfl_set_sysroot(void) {
|
||||
#if HAVE_ELFUTILS
|
||||
if (dlopen_dw(LOG_DEBUG) < 0)
|
||||
return false;
|
||||
return sym_dwfl_set_sysroot;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int dlopen_elf(int log_level) {
|
||||
#if HAVE_ELFUTILS
|
||||
int r;
|
||||
@@ -660,13 +673,13 @@ static int parse_core(
|
||||
|
||||
if (empty_or_root(root))
|
||||
root = NULL;
|
||||
#if HAVE_DWFL_SET_SYSROOT
|
||||
if (root && sym_dwfl_set_sysroot(c.dwfl, root) < 0)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Could not set root directory, dwfl_set_sysroot() failed: %s", sym_dwfl_errmsg(sym_dwfl_errno()));
|
||||
#else
|
||||
if (root)
|
||||
log_warning("Compiled without dwfl_set_sysroot() support, ignoring provided root directory.");
|
||||
#endif
|
||||
if (root) {
|
||||
if (sym_dwfl_set_sysroot) {
|
||||
if (sym_dwfl_set_sysroot(c.dwfl, root) < 0)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Could not set root directory, dwfl_set_sysroot() failed: %s", sym_dwfl_errmsg(sym_dwfl_errno()));
|
||||
} else
|
||||
log_warning("Loaded libdw does not support dwfl_set_sysroot(), ignoring provided root directory.");
|
||||
}
|
||||
|
||||
if (sym_dwfl_core_file_report(c.dwfl, c.elf, executable) < 0)
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), "Could not parse core file, dwfl_core_file_report() failed: %s", sym_dwfl_errmsg(sym_dwfl_errno()));
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
int dlopen_dw(int log_level);
|
||||
int dlopen_elf(int log_level);
|
||||
|
||||
bool dlopen_dw_has_dwfl_set_sysroot(void);
|
||||
|
||||
/* Parse an ELF object in a forked process, so that errors while iterating over
|
||||
* untrusted and potentially malicious data do not propagate to the main caller's process.
|
||||
* If fork_disable_dump, the child process will not dump core if it crashes. */
|
||||
|
||||
@@ -18,17 +18,15 @@ DLSYM_PROTOTYPE(archive_entry_fflags) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_filetype) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_free) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_gid) = NULL;
|
||||
#if HAVE_ARCHIVE_ENTRY_GID_IS_SET
|
||||
DLSYM_PROTOTYPE(archive_entry_gid_is_set) = NULL;
|
||||
#else
|
||||
int sym_archive_entry_gid_is_set(struct archive_entry *e) {
|
||||
static int missing_archive_entry_gid_is_set(struct archive_entry *e) {
|
||||
return gid_is_valid(sym_archive_entry_gid(e));
|
||||
}
|
||||
#endif
|
||||
DLSYM_PROTOTYPE(archive_entry_gid_is_set) = missing_archive_entry_gid_is_set;
|
||||
DLSYM_PROTOTYPE(archive_entry_hardlink) = NULL;
|
||||
#if HAVE_ARCHIVE_ENTRY_HARDLINK_IS_SET
|
||||
DLSYM_PROTOTYPE(archive_entry_hardlink_is_set) = NULL;
|
||||
#endif
|
||||
static int missing_archive_entry_hardlink_is_set(struct archive_entry *e) {
|
||||
return !!sym_archive_entry_hardlink(e);
|
||||
}
|
||||
DLSYM_PROTOTYPE(archive_entry_hardlink_is_set) = missing_archive_entry_hardlink_is_set;
|
||||
DLSYM_PROTOTYPE(archive_entry_mode) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_mtime) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_mtime_is_set) = NULL;
|
||||
@@ -53,13 +51,10 @@ DLSYM_PROTOTYPE(archive_entry_set_uid) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_sparse_add_entry) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_symlink) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_uid) = NULL;
|
||||
#if HAVE_ARCHIVE_ENTRY_UID_IS_SET
|
||||
DLSYM_PROTOTYPE(archive_entry_uid_is_set) = NULL;
|
||||
#else
|
||||
int sym_archive_entry_uid_is_set(struct archive_entry *e) {
|
||||
static int missing_archive_entry_uid_is_set(struct archive_entry *e) {
|
||||
return uid_is_valid(sym_archive_entry_uid(e));
|
||||
}
|
||||
#endif
|
||||
DLSYM_PROTOTYPE(archive_entry_uid_is_set) = missing_archive_entry_uid_is_set;
|
||||
DLSYM_PROTOTYPE(archive_entry_xattr_add_entry) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_xattr_next) = NULL;
|
||||
DLSYM_PROTOTYPE(archive_entry_xattr_reset) = NULL;
|
||||
@@ -84,13 +79,15 @@ DLSYM_PROTOTYPE(archive_write_set_format_pax) = NULL;
|
||||
|
||||
int dlopen_libarchive(int log_level) {
|
||||
#if HAVE_LIBARCHIVE
|
||||
int r;
|
||||
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"archive",
|
||||
"Support for decompressing archive files",
|
||||
SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
|
||||
"libarchive.so.13");
|
||||
|
||||
return dlopen_many_sym_or_warn(
|
||||
r = dlopen_many_sym_or_warn(
|
||||
&libarchive_dl,
|
||||
"libarchive.so.13",
|
||||
log_level,
|
||||
@@ -101,13 +98,7 @@ int dlopen_libarchive(int log_level) {
|
||||
DLSYM_ARG(archive_entry_filetype),
|
||||
DLSYM_ARG(archive_entry_free),
|
||||
DLSYM_ARG(archive_entry_gid),
|
||||
#if HAVE_ARCHIVE_ENTRY_GID_IS_SET
|
||||
DLSYM_ARG(archive_entry_gid_is_set),
|
||||
#endif
|
||||
DLSYM_ARG(archive_entry_hardlink),
|
||||
#if HAVE_ARCHIVE_ENTRY_HARDLINK_IS_SET
|
||||
DLSYM_ARG(archive_entry_hardlink_is_set),
|
||||
#endif
|
||||
DLSYM_ARG(archive_entry_mode),
|
||||
DLSYM_ARG(archive_entry_mtime),
|
||||
DLSYM_ARG(archive_entry_mtime_is_set),
|
||||
@@ -132,9 +123,6 @@ int dlopen_libarchive(int log_level) {
|
||||
DLSYM_ARG(archive_entry_sparse_add_entry),
|
||||
DLSYM_ARG(archive_entry_symlink),
|
||||
DLSYM_ARG(archive_entry_uid),
|
||||
#if HAVE_ARCHIVE_ENTRY_UID_IS_SET
|
||||
DLSYM_ARG(archive_entry_uid_is_set),
|
||||
#endif
|
||||
DLSYM_ARG(archive_entry_xattr_add_entry),
|
||||
DLSYM_ARG(archive_entry_xattr_next),
|
||||
DLSYM_ARG(archive_entry_xattr_reset),
|
||||
@@ -155,6 +143,16 @@ int dlopen_libarchive(int log_level) {
|
||||
DLSYM_ARG(archive_write_open_fd),
|
||||
DLSYM_ARG(archive_write_set_format_filter_by_ext),
|
||||
DLSYM_ARG(archive_write_set_format_pax));
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
/* Optional symbols: present in newer libarchive versions only. If missing, sym_X keeps its
|
||||
* fallback-function initializer (see above). */
|
||||
DLSYM_OPTIONAL(libarchive_dl, archive_entry_gid_is_set);
|
||||
DLSYM_OPTIONAL(libarchive_dl, archive_entry_uid_is_set);
|
||||
DLSYM_OPTIONAL(libarchive_dl, archive_entry_hardlink_is_set);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"libarchive support is not compiled in.");
|
||||
|
||||
@@ -9,6 +9,16 @@
|
||||
|
||||
#include "dlfcn-util.h"
|
||||
|
||||
/* Newer symbols that might not be in the header we build against. Always redeclare so DLSYM_PROTOTYPE's
|
||||
* typeof() resolves; suppress the warning when newer libarchive already declared them. */
|
||||
DISABLE_WARNING_REDUNDANT_DECLS;
|
||||
/* NOLINTBEGIN(readability-redundant-declaration) */
|
||||
extern int archive_entry_gid_is_set(struct archive_entry *e);
|
||||
extern int archive_entry_hardlink_is_set(struct archive_entry *e);
|
||||
extern int archive_entry_uid_is_set(struct archive_entry *e);
|
||||
/* NOLINTEND(readability-redundant-declaration) */
|
||||
REENABLE_WARNING;
|
||||
|
||||
extern DLSYM_PROTOTYPE(archive_entry_acl_add_entry);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_acl_next);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_acl_reset);
|
||||
@@ -16,19 +26,9 @@ extern DLSYM_PROTOTYPE(archive_entry_fflags);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_filetype);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_free);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_gid);
|
||||
#if HAVE_ARCHIVE_ENTRY_GID_IS_SET
|
||||
extern DLSYM_PROTOTYPE(archive_entry_gid_is_set);
|
||||
#else
|
||||
int sym_archive_entry_gid_is_set(struct archive_entry *e);
|
||||
#endif
|
||||
extern DLSYM_PROTOTYPE(archive_entry_hardlink);
|
||||
#if HAVE_ARCHIVE_ENTRY_HARDLINK_IS_SET
|
||||
extern DLSYM_PROTOTYPE(archive_entry_hardlink_is_set);
|
||||
#else
|
||||
static inline int sym_archive_entry_hardlink_is_set(struct archive_entry *e) {
|
||||
return !!sym_archive_entry_hardlink(e);
|
||||
}
|
||||
#endif
|
||||
extern DLSYM_PROTOTYPE(archive_entry_mode);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_mtime);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_mtime_is_set);
|
||||
@@ -53,11 +53,7 @@ extern DLSYM_PROTOTYPE(archive_entry_set_uid);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_sparse_add_entry);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_symlink);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_uid);
|
||||
#if HAVE_ARCHIVE_ENTRY_UID_IS_SET
|
||||
extern DLSYM_PROTOTYPE(archive_entry_uid_is_set);
|
||||
#else
|
||||
int sym_archive_entry_uid_is_set(struct archive_entry *e);
|
||||
#endif
|
||||
extern DLSYM_PROTOTYPE(archive_entry_xattr_add_entry);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_xattr_next);
|
||||
extern DLSYM_PROTOTYPE(archive_entry_xattr_reset);
|
||||
|
||||
Reference in New Issue
Block a user