- **bpf-util: rename from bpf-dlopen, unify version-specific symbol handling** - **cryptsetup: dlopen libcryptsetup in tokens** - **tree-wide: dlopen libpam in pam plugins** - **test-bus-marshal: dlopen() glib and libdbus instead of linking directly** - **lock-util: Simplify timeout for lock_generic_with_timeout()** - **color-util: simplify hsv_to_rgb, fix rgb_to_hsv negative-hue wrap** - **tree-wide: Use our own macros instead of fabs()/fmax()/fmin()** - **locale-util: dlopen() libintl instead of linking against it** - **home: Use log2u64() over log2()** - **meson: drop libdl, threads, and librt dependencies** - **libc: Use dlsym() from a constructor instead of weak symbols** - **libc: Make sure C23 versions of strtol(), sscanf() are not used**
This commit is contained in:
+20
-61
@@ -978,25 +978,13 @@ endif
|
||||
|
||||
#####################################################################
|
||||
|
||||
threads = dependency('threads')
|
||||
librt = cc.find_library('rt')
|
||||
libm = cc.find_library('m')
|
||||
libdl = cc.find_library('dl')
|
||||
|
||||
# On some distributions that use musl (e.g. Alpine), libintl.h may be provided by gettext rather than musl.
|
||||
# In that case, we need to explicitly link with libintl.so.
|
||||
if cc.has_function('dgettext',
|
||||
prefix : '''#include <libintl.h>''',
|
||||
args : '-D_GNU_SOURCE')
|
||||
libintl = []
|
||||
else
|
||||
libintl = cc.find_library('intl')
|
||||
if not cc.has_function('dgettext',
|
||||
prefix : '''#include <libintl.h>''',
|
||||
args : '-D_GNU_SOURCE',
|
||||
dependencies : libintl)
|
||||
error('dgettext() not found')
|
||||
endif
|
||||
# Header presence check only — dgettext itself is resolved via dlopen_libintl() at runtime, so we never
|
||||
# link against libintl. On glibc dgettext lives in libc; on musl gettext-dev provides libintl.h alongside
|
||||
# libintl.so.8 which we dlopen() if present.
|
||||
if not cc.has_header('libintl.h')
|
||||
error('libintl.h not found (install gettext / gettext-dev)')
|
||||
endif
|
||||
|
||||
# On some architectures, libatomic is required. But on some installations,
|
||||
@@ -1133,12 +1121,7 @@ if not libpam.found()
|
||||
# Debian older than bookworm and Ubuntu older than 22.10 do not provide the .pc file.
|
||||
libpam = cc.find_library('pam', required : feature)
|
||||
endif
|
||||
libpam_misc = dependency('pam_misc',
|
||||
required : feature.disabled() ? feature : false)
|
||||
if not libpam_misc.found()
|
||||
libpam_misc = cc.find_library('pam_misc', required : feature)
|
||||
endif
|
||||
conf.set10('HAVE_PAM', libpam.found() and libpam_misc.found())
|
||||
conf.set10('HAVE_PAM', libpam.found())
|
||||
libpam_cflags = libpam.partial_dependency(includes: true, compile_args: true)
|
||||
|
||||
libmicrohttpd = dependency('libmicrohttpd',
|
||||
@@ -1324,11 +1307,15 @@ libgobject = dependency('gobject-2.0',
|
||||
libgio = dependency('gio-2.0',
|
||||
required : get_option('glib'))
|
||||
conf.set10('HAVE_GLIB', libglib.found() and libgobject.found() and libgio.found())
|
||||
libglib_cflags = libglib.partial_dependency(includes: true, compile_args: true)
|
||||
libgobject_cflags = libgobject.partial_dependency(includes: true, compile_args: true)
|
||||
libgio_cflags = libgio.partial_dependency(includes: true, compile_args: true)
|
||||
|
||||
libdbus = dependency('dbus-1',
|
||||
version : '>= 1.3.2',
|
||||
required : get_option('dbus'))
|
||||
conf.set10('HAVE_DBUS', libdbus.found())
|
||||
libdbus_cflags = libdbus.partial_dependency(includes: true, compile_args: true)
|
||||
|
||||
dbusdatadir = libdbus.get_variable(pkgconfig: 'datadir', default_value: datadir) / 'dbus-1'
|
||||
|
||||
@@ -1704,14 +1691,13 @@ system_includes = [
|
||||
),
|
||||
]
|
||||
|
||||
if get_option('libc') == 'musl'
|
||||
system_include_args = [
|
||||
'-isystem', meson.project_build_root() / 'src/include/musl',
|
||||
'-isystem', meson.project_source_root() / 'src/include/musl',
|
||||
] + system_include_args
|
||||
libc_include_dir = 'src/include' / get_option('libc')
|
||||
system_include_args = [
|
||||
'-isystem', meson.project_build_root() / libc_include_dir,
|
||||
'-isystem', meson.project_source_root() / libc_include_dir,
|
||||
] + system_include_args
|
||||
|
||||
system_includes += include_directories('src/include/musl', is_system : true)
|
||||
endif
|
||||
system_includes += include_directories(libc_include_dir, is_system : true)
|
||||
|
||||
basic_includes = [
|
||||
include_directories(
|
||||
@@ -1768,9 +1754,7 @@ libsystemd = shared_library(
|
||||
link_with : [libc_wrapper_static,
|
||||
libbasic_static],
|
||||
link_whole : [libsystemd_static],
|
||||
dependencies : [librt,
|
||||
threads,
|
||||
userspace],
|
||||
dependencies : [userspace],
|
||||
link_depends : libsystemd_sym,
|
||||
install : true,
|
||||
install_tag: 'libsystemd',
|
||||
@@ -1789,14 +1773,11 @@ if static_libsystemd != 'false'
|
||||
install_tag: 'libsystemd',
|
||||
install_dir : libdir,
|
||||
pic : static_libsystemd_pic,
|
||||
dependencies : [libdl,
|
||||
libgcrypt_cflags,
|
||||
dependencies : [libgcrypt_cflags,
|
||||
liblz4_cflags,
|
||||
libm,
|
||||
librt,
|
||||
libxz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
userspace],
|
||||
c_args : libsystemd_c_args + (static_libsystemd_pic ? [] : ['-fno-PIC']))
|
||||
|
||||
@@ -1814,8 +1795,7 @@ libudev = shared_library(
|
||||
'-Wl,--version-script=' + libudev_sym_path],
|
||||
link_with : [libsystemd_static],
|
||||
link_whole : libudev_basic,
|
||||
dependencies : [threads,
|
||||
userspace],
|
||||
dependencies : [userspace],
|
||||
link_depends : libudev_sym,
|
||||
install : true,
|
||||
install_tag: 'libudev',
|
||||
@@ -1932,10 +1912,6 @@ nss_template = {
|
||||
libshared_static,
|
||||
libbasic_static,
|
||||
],
|
||||
'dependencies' : [
|
||||
librt,
|
||||
threads,
|
||||
],
|
||||
'install' : true,
|
||||
'install_tag' : 'nss',
|
||||
'install_dir' : libdir,
|
||||
@@ -1948,24 +1924,7 @@ pam_template = {
|
||||
libsystemd_static,
|
||||
libshared_static,
|
||||
],
|
||||
'dependencies' : [
|
||||
# Note: our PAM modules also call dlopen_libpam() and use
|
||||
# symbols acquired through that, hence the explicit dep here is
|
||||
# strictly speaking unnecessary. We put it in place anyway,
|
||||
# since for the PAM modules we cannot avoid libpam anyway,
|
||||
# after all they are loaded *by* libpam, and hence there's no
|
||||
# loss in having explicit deps here, but there's a win: it
|
||||
# makes the deps more visible.
|
||||
#
|
||||
# (In case you wonder why we do dlopen_libpam() from the PAM
|
||||
# modules in the first place: that's mostly so that all our PAM
|
||||
# code (regardless if our PAM modules or our PAM consuming
|
||||
# programs) can use the same helpers, which hence go via
|
||||
# dlopen_libpam().
|
||||
libpam_misc,
|
||||
libpam,
|
||||
threads,
|
||||
],
|
||||
'dependencies' : libpam_cflags,
|
||||
'install' : true,
|
||||
'install_tag' : 'pam',
|
||||
'install_dir' : pamlibdir,
|
||||
|
||||
@@ -8,6 +8,7 @@ Distribution=|fedora
|
||||
PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/systemd.prepare
|
||||
Packages=
|
||||
coreutils
|
||||
cryptsetup-libs
|
||||
policycoreutils
|
||||
swtpm-tools
|
||||
tpm2-tools
|
||||
|
||||
@@ -9,6 +9,7 @@ Packages=
|
||||
btrfs-progs
|
||||
coreutils
|
||||
kmod
|
||||
libcryptsetup12
|
||||
policycoreutils
|
||||
tpm2.0-tools
|
||||
|
||||
|
||||
@@ -7,7 +7,12 @@
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef __GLIBC__
|
||||
#include "sd-dlopen.h"
|
||||
#endif
|
||||
|
||||
#include "dirent-util.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "env-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@@ -22,6 +27,32 @@
|
||||
#include "strv.h"
|
||||
#include "utf8.h"
|
||||
|
||||
#ifdef __GLIBC__
|
||||
DLSYM_PROTOTYPE(dgettext) = dgettext;
|
||||
#else
|
||||
DLSYM_PROTOTYPE(dgettext) = NULL;
|
||||
#endif
|
||||
|
||||
int dlopen_libintl(int log_level) {
|
||||
#ifdef __GLIBC__
|
||||
return 1;
|
||||
#else
|
||||
static void *libintl_dl = NULL;
|
||||
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"intl",
|
||||
"Support for message translation via gettext",
|
||||
SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
|
||||
"libintl.so.8");
|
||||
|
||||
return dlopen_many_sym_or_warn(
|
||||
&libintl_dl,
|
||||
"libintl.so.8",
|
||||
log_level,
|
||||
DLSYM_ARG(dgettext));
|
||||
#endif
|
||||
}
|
||||
|
||||
static char* normalize_locale(const char *name) {
|
||||
const char *e;
|
||||
|
||||
|
||||
+12
-1
@@ -1,9 +1,18 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <libintl.h> /* IWYU pragma: export */
|
||||
#include <locale.h> /* IWYU pragma: export */
|
||||
|
||||
#include "basic-forward.h"
|
||||
#include "dlfcn-util.h"
|
||||
|
||||
/* format_arg(2) propagates the format-string nature of the second argument to the return value, so that
|
||||
* printf(_("Hello %s"), name) still gets checked. It survives both DLSYM_PROTOTYPE's typeof() and the
|
||||
* ternary in _() below — verified on gcc and clang. */
|
||||
extern DLSYM_PROTOTYPE(dgettext) __attribute__((format_arg(2)));
|
||||
|
||||
int dlopen_libintl(int log_level);
|
||||
|
||||
typedef enum LocaleVariable {
|
||||
/* We don't list LC_ALL here on purpose. People should be
|
||||
@@ -31,7 +40,9 @@ int get_locales(char ***ret);
|
||||
bool locale_is_valid(const char *name);
|
||||
int locale_is_installed(const char *name);
|
||||
|
||||
#define _(String) dgettext(GETTEXT_PACKAGE, String)
|
||||
/* Falls back to the untranslated string if dlopen_libintl() hasn't run or has failed, so callers don't have
|
||||
* to gate every translatable message on a runtime check. */
|
||||
#define _(String) (sym_dgettext ? sym_dgettext(GETTEXT_PACKAGE, (String)) : (String))
|
||||
#define N_(String) String
|
||||
|
||||
bool is_locale_utf8(void);
|
||||
|
||||
+1
-26
@@ -1,7 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -227,25 +226,6 @@ int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeo
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to flock block device in child process: %m");
|
||||
if (r == 0) {
|
||||
struct sigevent sev = {
|
||||
.sigev_notify = SIGEV_SIGNAL,
|
||||
.sigev_signo = SIGALRM,
|
||||
};
|
||||
timer_t id;
|
||||
|
||||
if (timer_create(CLOCK_MONOTONIC, &sev, &id) < 0) {
|
||||
log_error_errno(errno, "Failed to allocate CLOCK_MONOTONIC timer: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct itimerspec its = {};
|
||||
timespec_store(&its.it_value, timeout);
|
||||
|
||||
if (timer_settime(id, /* flags= */ 0, &its, NULL) < 0) {
|
||||
log_error_errno(errno, "Failed to start CLOCK_MONOTONIC timer: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (lock_generic(fd, type, operation) < 0) {
|
||||
log_error_errno(errno, "Unable to get an exclusive lock on the device: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
@@ -255,7 +235,7 @@ int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeo
|
||||
}
|
||||
|
||||
siginfo_t status;
|
||||
r = pidref_wait_for_terminate(&pidref, &status);
|
||||
r = pidref_wait_for_terminate_full(&pidref, timeout, &status);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -270,11 +250,6 @@ int lock_generic_with_timeout(int fd, LockType type, int operation, usec_t timeo
|
||||
return 0;
|
||||
|
||||
case CLD_KILLED:
|
||||
if (status.si_status == SIGALRM)
|
||||
return -ETIMEDOUT;
|
||||
|
||||
_fallthrough_;
|
||||
|
||||
case CLD_DUMPED:
|
||||
return -EPROTO;
|
||||
|
||||
|
||||
@@ -212,15 +212,12 @@ libbasic_static = static_library(
|
||||
include_directories : basic_includes,
|
||||
implicit_include_directories : false,
|
||||
dependencies : [libbzip2_cflags,
|
||||
libdl,
|
||||
libgcrypt_cflags,
|
||||
liblz4_cflags,
|
||||
libm,
|
||||
librt,
|
||||
libxz_cflags,
|
||||
libz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
userspace],
|
||||
c_args : ['-fvisibility=default'],
|
||||
build_by_default : false)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* fine given that LGPL-2.1-or-later downgrades to GPL if needed.
|
||||
*/
|
||||
|
||||
#include "bpf-dlopen.h" /* IWYU pragma: keep */
|
||||
#include "bpf-util.h" /* IWYU pragma: keep */
|
||||
|
||||
/* libbpf is used via dlopen(), so rename symbols */
|
||||
#define bpf_object__attach_skeleton sym_bpf_object__attach_skeleton
|
||||
|
||||
+1
-1
@@ -394,7 +394,7 @@ foreach program : bpf_programs
|
||||
# Keeping it out of bpf_programs_by_name also keeps it out of the
|
||||
# clang-tidy per-source test loop, which would otherwise fall back
|
||||
# to a BPF compile_commands.json entry (no -Isrc/shared) and fail
|
||||
# to resolve bpf-dlopen.h.
|
||||
# to resolve bpf-util.h.
|
||||
configure_file(
|
||||
input : 'bpf-skel-wrapper.h.in',
|
||||
output : name + '-skel.h',
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
#if BPF_FRAMEWORK
|
||||
/* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "bpf-link.h"
|
||||
#include "bind-iface-skel.h"
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
#if BPF_FRAMEWORK
|
||||
/* libbpf, clang and llc compile time dependencies are satisfied */
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "bpf-link.h"
|
||||
#include "restrict-fs-skel.h"
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ const char* const restrict_fsaccess_link_names[_RESTRICT_FILESYSTEM_ACCESS_LINK_
|
||||
};
|
||||
|
||||
#if BPF_FRAMEWORK && HAVE_LSM_INTEGRITY_TYPE
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "bpf-link.h"
|
||||
#include "restrict-fsaccess-skel.h"
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
#if BPF_FRAMEWORK
|
||||
/* libbpf, clang and llc compile time dependencies are satisfied */
|
||||
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "bpf-link.h"
|
||||
#include "restrict-ifaces-skel.h"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
#if BPF_FRAMEWORK
|
||||
/* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "bpf-link.h"
|
||||
#include "socket-bind-api.bpf.h"
|
||||
#include "socket-bind-skel.h"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "ask-password-api.h"
|
||||
#include "barrier.h"
|
||||
#include "bitfield.h"
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "bpf-restrict-fs.h"
|
||||
#include "btrfs-util.h"
|
||||
#include "capability-util.h"
|
||||
|
||||
@@ -148,13 +148,10 @@ libcore_static = static_library(
|
||||
dependencies : [libaudit_cflags,
|
||||
libbpf_cflags,
|
||||
libcryptsetup_cflags,
|
||||
libdl,
|
||||
libm,
|
||||
libmount_cflags,
|
||||
librt,
|
||||
libseccomp_cflags,
|
||||
libselinux_cflags,
|
||||
threads,
|
||||
userspace],
|
||||
build_by_default : false)
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ common_dependencies = [
|
||||
liblz4_cflags,
|
||||
libxz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
]
|
||||
|
||||
executables += [
|
||||
|
||||
@@ -12,7 +12,6 @@ executables += [
|
||||
'dependencies' : [
|
||||
libmount_cflags,
|
||||
libopenssl_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -22,7 +22,6 @@ executables += [
|
||||
'sources' : systemd_cryptenroll_sources,
|
||||
'dependencies' : [
|
||||
libcryptsetup_cflags,
|
||||
libdl,
|
||||
libfido2_cflags,
|
||||
libopenssl_cflags,
|
||||
libp11kit_cflags,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <libcryptsetup.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "sd-json.h"
|
||||
|
||||
@@ -37,8 +38,12 @@ _public_ int cryptsetup_token_open_pin(
|
||||
assert(pin || pin_size == 0);
|
||||
assert(token >= 0);
|
||||
|
||||
r = dlopen_cryptsetup(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* This must not fail at this moment (internal error) */
|
||||
r = crypt_token_json_get(cd, token, &json);
|
||||
r = sym_crypt_token_json_get(cd, token, &json);
|
||||
/* Use assert_se() here to avoid emitting warning with -DNDEBUG */
|
||||
assert_se(token == r);
|
||||
assert(json);
|
||||
@@ -98,6 +103,9 @@ _public_ void cryptsetup_token_dump(
|
||||
|
||||
assert(json);
|
||||
|
||||
if (dlopen_cryptsetup(LOG_DEBUG) < 0)
|
||||
return;
|
||||
|
||||
r = parse_luks2_fido2_data(cd, json, &rp_id, &salt, &salt_size, &cid, &cid_size, &required);
|
||||
if (r < 0)
|
||||
return (void) crypt_log_debug_errno(cd, r, "Failed to parse " TOKEN_NAME " metadata: %m.");
|
||||
@@ -162,6 +170,10 @@ _public_ int cryptsetup_token_validate(
|
||||
|
||||
assert(json);
|
||||
|
||||
r = dlopen_cryptsetup(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_json_parse(json, SD_JSON_PARSE_MUST_BE_OBJECT, &v, /* reterr_line= */ NULL, /* reterr_column= */ NULL);
|
||||
if (r < 0)
|
||||
return crypt_log_debug_errno(cd, r, "Could not parse " TOKEN_NAME " json object: %m.");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <libcryptsetup.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "sd-json.h"
|
||||
|
||||
@@ -36,8 +37,12 @@ _public_ int cryptsetup_token_open_pin(
|
||||
assert(pin || pin_size == 0);
|
||||
assert(token >= 0);
|
||||
|
||||
r = dlopen_cryptsetup(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* This must not fail at this moment (internal error) */
|
||||
r = crypt_token_json_get(cd, token, &json);
|
||||
r = sym_crypt_token_json_get(cd, token, &json);
|
||||
/* Use assert_se() here to avoid emitting warning with -DNDEBUG */
|
||||
assert_se(token == r);
|
||||
assert(json);
|
||||
@@ -89,6 +94,9 @@ _public_ void cryptsetup_token_dump(
|
||||
_cleanup_free_ char *pkcs11_uri = NULL, *key_str = NULL;
|
||||
_cleanup_free_ void *pkcs11_key = NULL;
|
||||
|
||||
if (dlopen_cryptsetup(LOG_DEBUG) < 0)
|
||||
return;
|
||||
|
||||
r = parse_luks2_pkcs11_data(cd, json, &pkcs11_uri, &pkcs11_key, &pkcs11_key_size);
|
||||
if (r < 0)
|
||||
return (void) crypt_log_debug_errno(cd, r, "Failed to parse " TOKEN_NAME " metadata: %m.");
|
||||
@@ -115,6 +123,10 @@ _public_ int cryptsetup_token_validate(
|
||||
sd_json_variant *w;
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
|
||||
r = dlopen_cryptsetup(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_json_parse(json, SD_JSON_PARSE_MUST_BE_OBJECT, &v, /* reterr_line= */ NULL, /* reterr_column= */ NULL);
|
||||
if (r < 0)
|
||||
return crypt_log_debug_errno(cd, r, "Could not parse " TOKEN_NAME " json object: %m.");
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <libcryptsetup.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "alloc-util.h"
|
||||
#include "cryptsetup-token.h"
|
||||
@@ -60,8 +61,12 @@ _public_ int cryptsetup_token_open_pin(
|
||||
assert(ret_password);
|
||||
assert(ret_password_len);
|
||||
|
||||
r = dlopen_cryptsetup(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* This must not fail at this moment (internal error) */
|
||||
r = crypt_token_json_get(cd, token, &json);
|
||||
r = sym_crypt_token_json_get(cd, token, &json);
|
||||
assert(token == r);
|
||||
assert(json);
|
||||
|
||||
@@ -186,6 +191,9 @@ _public_ void cryptsetup_token_dump(
|
||||
|
||||
assert(json);
|
||||
|
||||
if (dlopen_cryptsetup(LOG_DEBUG) < 0)
|
||||
return;
|
||||
|
||||
r = sd_json_parse(json, SD_JSON_PARSE_MUST_BE_OBJECT, &v, /* reterr_line= */ NULL, /* reterr_column= */ NULL);
|
||||
if (r < 0)
|
||||
return (void) crypt_log_debug_errno(cd, r, "Failed to parse " TOKEN_NAME " JSON object: %m");
|
||||
@@ -275,6 +283,10 @@ _public_ int cryptsetup_token_validate(
|
||||
|
||||
assert(json);
|
||||
|
||||
r = dlopen_cryptsetup(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = sd_json_parse(json, SD_JSON_PARSE_MUST_BE_OBJECT, &v, /* reterr_line= */ NULL, /* reterr_column= */ NULL);
|
||||
if (r < 0)
|
||||
return crypt_log_debug_errno(cd, r, "Could not parse " TOKEN_NAME " json object: %m");
|
||||
|
||||
@@ -2,22 +2,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libcryptsetup.h>
|
||||
|
||||
#include "cryptsetup-util.h"
|
||||
#include "shared-forward.h"
|
||||
|
||||
/* crypt_dump() internal indentation magic */
|
||||
#define CRYPT_DUMP_LINE_SEP "\n\t "
|
||||
|
||||
#define crypt_log_debug(cd, ...) crypt_logf(cd, CRYPT_LOG_DEBUG, __VA_ARGS__)
|
||||
#define crypt_log_error(cd, ...) crypt_logf(cd, CRYPT_LOG_ERROR, __VA_ARGS__)
|
||||
#define crypt_log_verbose(cd, ...) crypt_logf(cd, CRYPT_LOG_VERBOSE, __VA_ARGS__)
|
||||
#define crypt_log(cd, ...) crypt_logf(cd, CRYPT_LOG_NORMAL, __VA_ARGS__)
|
||||
#define crypt_log_debug(cd, ...) sym_crypt_logf(cd, CRYPT_LOG_DEBUG, __VA_ARGS__)
|
||||
#define crypt_log_error(cd, ...) sym_crypt_logf(cd, CRYPT_LOG_ERROR, __VA_ARGS__)
|
||||
#define crypt_log_verbose(cd, ...) sym_crypt_logf(cd, CRYPT_LOG_VERBOSE, __VA_ARGS__)
|
||||
#define crypt_log(cd, ...) sym_crypt_logf(cd, CRYPT_LOG_NORMAL, __VA_ARGS__)
|
||||
|
||||
#define crypt_log_full_errno(cd, e, lvl, ...) ({ \
|
||||
int _e = ABS(e), _s = errno; \
|
||||
errno = _e; \
|
||||
crypt_logf(cd, lvl, __VA_ARGS__); \
|
||||
sym_crypt_logf(cd, lvl, __VA_ARGS__); \
|
||||
errno = _s; \
|
||||
-_e; \
|
||||
})
|
||||
|
||||
@@ -45,8 +45,8 @@ modules += [
|
||||
],
|
||||
'sources' : cryptsetup_token_systemd_tpm2_sources,
|
||||
'dependencies' : [
|
||||
libcryptsetup,
|
||||
tpm2,
|
||||
libcryptsetup_cflags,
|
||||
tpm2_cflags,
|
||||
],
|
||||
},
|
||||
template + {
|
||||
@@ -57,7 +57,7 @@ modules += [
|
||||
],
|
||||
'sources' : cryptsetup_token_systemd_fido2_sources,
|
||||
'dependencies' : [
|
||||
libcryptsetup,
|
||||
libcryptsetup_cflags,
|
||||
libfido2_cflags,
|
||||
],
|
||||
},
|
||||
@@ -69,7 +69,7 @@ modules += [
|
||||
],
|
||||
'sources' : cryptsetup_token_systemd_pkcs11_sources,
|
||||
'dependencies' : [
|
||||
libcryptsetup,
|
||||
libcryptsetup_cflags,
|
||||
libp11kit_cflags,
|
||||
],
|
||||
},
|
||||
|
||||
@@ -180,12 +180,14 @@
|
||||
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
|
||||
})
|
||||
|
||||
#ifdef __clang__
|
||||
# define ABS(a) __builtin_llabs(a)
|
||||
#else
|
||||
# define ABS(a) __builtin_imaxabs(a)
|
||||
#endif
|
||||
assert_cc(sizeof(long long) == sizeof(intmax_t));
|
||||
#define ABS(a) _Generic((a), \
|
||||
float: __builtin_fabsf((float) (a)), \
|
||||
double: __builtin_fabs((double) (a)), \
|
||||
long double: __builtin_fabsl((long double) (a)), \
|
||||
unsigned long long: (a), \
|
||||
unsigned long: (a), \
|
||||
unsigned int: (a), \
|
||||
default: __builtin_llabs((long long) (a)))
|
||||
|
||||
#define IS_UNSIGNED_INTEGER_TYPE(type) \
|
||||
(__builtin_types_compatible_p(typeof(type), unsigned char) || \
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <grp.h>
|
||||
#include <linux/fscrypt.h>
|
||||
#include <linux/magic.h>
|
||||
#include <math.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/inotify.h>
|
||||
#include <sys/ioctl.h>
|
||||
@@ -41,6 +40,7 @@
|
||||
#include "homed-manager-bus.h"
|
||||
#include "homed-operation.h"
|
||||
#include "homed-varlink.h"
|
||||
#include "logarithm.h"
|
||||
#include "mkdir.h"
|
||||
#include "notify-recv.h"
|
||||
#include "ordered-set.h"
|
||||
@@ -1937,9 +1937,9 @@ static int manager_rebalance_calculate(Manager *m) {
|
||||
}
|
||||
|
||||
/* Scale next rebalancing interval based on the least amount of space of any of the home
|
||||
* directories. We pick a time in the range 1min … 15min, scaled by log2(min_free), so that:
|
||||
* 10M → ~0.7min, 100M → ~2.7min, 1G → ~4.6min, 10G → ~6.5min, 100G ~8.4 */
|
||||
m->rebalance_interval_usec = (usec_t) CLAMP((LESS_BY(log2(min_free), 22)*15*USEC_PER_MINUTE)/26,
|
||||
* directories. We pick a time in the range 1min … 15min, scaled by floor(log2(min_free)),
|
||||
* so that: 10M → ~0.6min, 100M → ~2.3min, 1G → ~4.0min, 10G → ~6.3min, 100G → ~8.1min */
|
||||
m->rebalance_interval_usec = (usec_t) CLAMP((LESS_BY(log2u64(min_free), 22u)*15*USEC_PER_MINUTE)/26,
|
||||
1 * USEC_PER_MINUTE,
|
||||
15 * USEC_PER_MINUTE);
|
||||
|
||||
|
||||
+1
-14
@@ -67,11 +67,7 @@ executables += [
|
||||
'dbus' : true,
|
||||
'sources' : systemd_homed_sources,
|
||||
'extract' : systemd_homed_extract_sources,
|
||||
'dependencies' : [
|
||||
libm,
|
||||
libopenssl_cflags,
|
||||
threads,
|
||||
],
|
||||
'dependencies' : libopenssl_cflags,
|
||||
},
|
||||
libexec_template + {
|
||||
'name' : 'systemd-homework',
|
||||
@@ -82,7 +78,6 @@ executables += [
|
||||
libfdisk_cflags,
|
||||
libopenssl_cflags,
|
||||
libp11kit_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
executable_template + {
|
||||
@@ -92,10 +87,8 @@ executables += [
|
||||
'extract' : homectl_extract,
|
||||
'objects' : ['systemd-homed'],
|
||||
'dependencies' : [
|
||||
libdl,
|
||||
libopenssl_cflags,
|
||||
libp11kit_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
test_template + {
|
||||
@@ -114,12 +107,6 @@ modules += [
|
||||
'name' : 'pam_systemd_home',
|
||||
'conditions' : ['HAVE_PAM'],
|
||||
'sources' : pam_systemd_home_sources,
|
||||
'dependencies' : [
|
||||
libintl,
|
||||
libpam_misc,
|
||||
libpam,
|
||||
threads,
|
||||
],
|
||||
'version-script' : meson.current_source_dir() / 'pam_systemd_home.sym',
|
||||
},
|
||||
]
|
||||
|
||||
+48
-37
@@ -1,8 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <libintl.h>
|
||||
#include <security/pam_misc.h>
|
||||
|
||||
#include "sd-bus.h"
|
||||
|
||||
#include "alloc-util.h"
|
||||
@@ -45,7 +42,7 @@ static int parse_argv(
|
||||
|
||||
k = parse_boolean(v);
|
||||
if (k < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse suspend= argument, ignoring: %s", v);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse suspend= argument, ignoring: %s", v);
|
||||
else if (flags)
|
||||
SET_FLAG(*flags, ACQUIRE_PLEASE_SUSPEND, k);
|
||||
|
||||
@@ -57,12 +54,12 @@ static int parse_argv(
|
||||
int k;
|
||||
k = parse_boolean(v);
|
||||
if (k < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", v);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", v);
|
||||
else if (debug)
|
||||
*debug = k;
|
||||
|
||||
} else
|
||||
pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -76,7 +73,7 @@ static int parse_env(pam_handle_t *pamh, AcquireHomeFlags *flags) {
|
||||
* easy to declare the features of a display manager in code rather than configuration, and this is
|
||||
* really a feature of code */
|
||||
|
||||
v = pam_getenv(pamh, "SYSTEMD_HOME_SUSPEND");
|
||||
v = sym_pam_getenv(pamh, "SYSTEMD_HOME_SUSPEND");
|
||||
if (!v) {
|
||||
/* Also check the process env block, so that people can control this via an env var from the
|
||||
* outside of our process. */
|
||||
@@ -87,7 +84,7 @@ static int parse_env(pam_handle_t *pamh, AcquireHomeFlags *flags) {
|
||||
|
||||
r = parse_boolean(v);
|
||||
if (r < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse $SYSTEMD_HOME_SUSPEND argument, ignoring: %s", v);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse $SYSTEMD_HOME_SUSPEND argument, ignoring: %s", v);
|
||||
else if (flags)
|
||||
SET_FLAG(*flags, ACQUIRE_PLEASE_SUSPEND, r);
|
||||
|
||||
@@ -106,7 +103,7 @@ static int acquire_user_record(
|
||||
assert(pamh);
|
||||
|
||||
if (!username) {
|
||||
r = pam_get_user(pamh, &username, NULL);
|
||||
r = sym_pam_get_user(pamh, &username, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
|
||||
if (isempty(username))
|
||||
@@ -149,7 +146,7 @@ static int acquire_user_record(
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
/* Let's use the cache, so that we can share it between the session and the authentication hooks */
|
||||
r = pam_get_data(pamh, homed_field, (const void**) &json);
|
||||
r = sym_pam_get_data(pamh, homed_field, (const void**) &json);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM user record data: @PAMERR@");
|
||||
if (r == PAM_SUCCESS && json) {
|
||||
@@ -211,13 +208,13 @@ static int acquire_user_record(
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SERVICE_ERR,
|
||||
"Acquired user record does not match user name.");
|
||||
|
||||
/* Update the 'username' pointer to point to our own record now. The pam_set_item() call below is
|
||||
/* Update the 'username' pointer to point to our own record now. The sym_pam_set_item() call below is
|
||||
* going to invalidate the old version after all */
|
||||
username = ur->user_name;
|
||||
|
||||
/* We passed all checks. Let's now make sure the rest of the PAM stack continues with the primary,
|
||||
* normalized name of the user record (i.e. not an alias or so). */
|
||||
r = pam_set_item(pamh, PAM_USER, ur->user_name);
|
||||
r = sym_pam_set_item(pamh, PAM_USER, ur->user_name);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to update username PAM item to '%s': @PAMERR@", ur->user_name);
|
||||
@@ -230,7 +227,7 @@ static int acquire_user_record(
|
||||
if (!json_copy)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_set_data(pamh, homed_field, json_copy, pam_cleanup_free);
|
||||
r = sym_pam_set_data(pamh, homed_field, json_copy, pam_cleanup_free);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM user record data '%s': @PAMERR@", homed_field);
|
||||
@@ -246,7 +243,7 @@ static int acquire_user_record(
|
||||
if (!generic_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_set_data(pamh, generic_field, json_copy, pam_cleanup_free);
|
||||
r = sym_pam_set_data(pamh, generic_field, json_copy, pam_cleanup_free);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM user record data '%s': @PAMERR@", generic_field);
|
||||
@@ -256,7 +253,7 @@ static int acquire_user_record(
|
||||
|
||||
/* Let's store the area we parsed out of the name in an env var, so that pam_systemd later can honour it. */
|
||||
if (area) {
|
||||
r = pam_misc_setenv(pamh, "XDG_AREA", area, /* readonly= */ 0);
|
||||
r = pam_putenv_assign(pamh, "XDG_AREA", area);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set environment variable $XDG_AREA to '%s': @PAMERR@", area);
|
||||
@@ -269,7 +266,7 @@ static int acquire_user_record(
|
||||
|
||||
user_unknown:
|
||||
/* Cache this, so that we don't check again */
|
||||
r = pam_set_data(pamh, homed_field, POINTER_MAX, NULL);
|
||||
r = sym_pam_set_data(pamh, homed_field, POINTER_MAX, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM user record data '%s' to invalid, ignoring: @PAMERR@",
|
||||
@@ -289,7 +286,7 @@ static int release_user_record(pam_handle_t *pamh, const char *username) {
|
||||
if (!homed_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_set_data(pamh, homed_field, NULL, NULL);
|
||||
r = sym_pam_set_data(pamh, homed_field, NULL, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to release PAM user record data '%s': @PAMERR@", homed_field);
|
||||
@@ -298,7 +295,7 @@ static int release_user_record(pam_handle_t *pamh, const char *username) {
|
||||
if (!generic_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
k = pam_set_data(pamh, generic_field, NULL, NULL);
|
||||
k = sym_pam_set_data(pamh, generic_field, NULL, NULL);
|
||||
if (k != PAM_SUCCESS)
|
||||
pam_syslog_pam_error(pamh, LOG_ERR, k,
|
||||
"Failed to release PAM user record data '%s': @PAMERR@", generic_field);
|
||||
@@ -569,7 +566,7 @@ static int acquire_home(
|
||||
* prompt the user for the missing unlock credentials, and then chainload the real shell.
|
||||
*/
|
||||
|
||||
r = pam_get_user(pamh, &username, NULL);
|
||||
r = sym_pam_get_user(pamh, &username, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
|
||||
if (isempty(username))
|
||||
@@ -580,7 +577,7 @@ static int acquire_home(
|
||||
if (!fd_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_get_data(pamh, fd_field, &home_fd_ptr);
|
||||
r = sym_pam_get_data(pamh, fd_field, &home_fd_ptr);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to retrieve PAM home reference fd: @PAMERR@");
|
||||
@@ -618,7 +615,7 @@ static int acquire_home(
|
||||
/* If there's already a cached password, use it. But if not let's authenticate
|
||||
* without anything, maybe some other authentication mechanism systemd-homed
|
||||
* implements (such as PKCS#11) allows us to authenticate without anything else. */
|
||||
r = pam_get_item(pamh, PAM_AUTHTOK, (const void**) &cached_password);
|
||||
r = sym_pam_get_item(pamh, PAM_AUTHTOK, (const void**) &cached_password);
|
||||
if (!IN_SET(r, PAM_BAD_ITEM, PAM_SUCCESS))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to get cached password: @PAMERR@");
|
||||
@@ -681,7 +678,7 @@ static int acquire_home(
|
||||
(void) pam_prompt_graceful(pamh, PAM_ERROR_MSG, NULL, _("Home of user %s is currently locked, please unlock locally first."), ur->user_name);
|
||||
|
||||
if (FLAGS_SET(flags, ACQUIRE_MUST_AUTHENTICATE))
|
||||
pam_syslog(pamh, LOG_ERR, "Failed to prompt for password/prompt.");
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Failed to prompt for password/prompt.");
|
||||
else
|
||||
pam_debug_syslog(pamh, debug, "Failed to prompt for password/prompt.");
|
||||
|
||||
@@ -720,12 +717,12 @@ static int acquire_home(
|
||||
|
||||
/* Later PAM modules may need the auth token, but only during pam_authenticate. */
|
||||
if (FLAGS_SET(flags, ACQUIRE_MUST_AUTHENTICATE) && !strv_isempty(secret->password)) {
|
||||
r = pam_set_item(pamh, PAM_AUTHTOK, *secret->password);
|
||||
r = sym_pam_set_item(pamh, PAM_AUTHTOK, *secret->password);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM auth token: @PAMERR@");
|
||||
}
|
||||
|
||||
r = pam_set_data(pamh, fd_field, FD_TO_PTR(acquired_fd), cleanup_home_fd);
|
||||
r = sym_pam_set_data(pamh, fd_field, FD_TO_PTR(acquired_fd), cleanup_home_fd);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM bus data: @PAMERR@");
|
||||
TAKE_FD(acquired_fd);
|
||||
@@ -744,13 +741,13 @@ static int acquire_home(
|
||||
* manager for us (since it would see an inaccessible home directory). Hence set an environment
|
||||
* variable that pam_systemd looks for). */
|
||||
if (unrestricted) {
|
||||
r = pam_putenv(pamh, "XDG_SESSION_INCOMPLETE=1");
|
||||
r = sym_pam_putenv(pamh, "XDG_SESSION_INCOMPLETE=1");
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_WARNING, r, "Failed to set XDG_SESSION_INCOMPLETE= environment variable: @PAMERR@");
|
||||
|
||||
pam_syslog(pamh, LOG_NOTICE, "Home for user %s acquired in incomplete mode, requires later activation.", ur->user_name);
|
||||
sym_pam_syslog(pamh, LOG_NOTICE, "Home for user %s acquired in incomplete mode, requires later activation.", ur->user_name);
|
||||
} else
|
||||
pam_syslog(pamh, LOG_NOTICE, "Home for user %s successfully acquired.", ur->user_name);
|
||||
sym_pam_syslog(pamh, LOG_NOTICE, "Home for user %s successfully acquired.", ur->user_name);
|
||||
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
@@ -767,13 +764,13 @@ static int release_home_fd(pam_handle_t *pamh, const char *username) {
|
||||
if (!fd_field)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_get_data(pamh, fd_field, &home_fd_ptr);
|
||||
r = sym_pam_get_data(pamh, fd_field, &home_fd_ptr);
|
||||
if (r == PAM_NO_MODULE_DATA || (r == PAM_SUCCESS && PTR_TO_FD(home_fd_ptr) < 0))
|
||||
return PAM_NO_MODULE_DATA;
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to retrieve PAM home reference fd: @PAMERR@");
|
||||
|
||||
r = pam_set_data(pamh, fd_field, NULL, NULL);
|
||||
r = sym_pam_set_data(pamh, fd_field, NULL, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to release PAM home reference fd: @PAMERR@");
|
||||
|
||||
@@ -793,6 +790,8 @@ _public_ PAM_EXTERN int pam_sm_authenticate(
|
||||
if (r < 0)
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
(void) dlopen_libintl(LOG_DEBUG); /* best-effort: messages won't be translated if this fails */
|
||||
|
||||
pam_log_setup();
|
||||
|
||||
if (parse_env(pamh, &flags) < 0)
|
||||
@@ -858,6 +857,8 @@ _public_ PAM_EXTERN int pam_sm_open_session(
|
||||
if (r < 0)
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
(void) dlopen_libintl(LOG_DEBUG); /* best-effort: messages won't be translated if this fails */
|
||||
|
||||
pam_log_setup();
|
||||
|
||||
if (parse_env(pamh, &flags) < 0)
|
||||
@@ -887,12 +888,12 @@ _public_ PAM_EXTERN int pam_sm_open_session(
|
||||
if (r != PAM_SUCCESS)
|
||||
return r;
|
||||
|
||||
r = pam_putenv(pamh, "SYSTEMD_HOME=1");
|
||||
r = sym_pam_putenv(pamh, "SYSTEMD_HOME=1");
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM environment variable $SYSTEMD_HOME: @PAMERR@");
|
||||
|
||||
r = pam_putenv(pamh, FLAGS_SET(flags, ACQUIRE_PLEASE_SUSPEND) ? "SYSTEMD_HOME_SUSPEND=1" : "SYSTEMD_HOME_SUSPEND=0");
|
||||
r = sym_pam_putenv(pamh, FLAGS_SET(flags, ACQUIRE_PLEASE_SUSPEND) ? "SYSTEMD_HOME_SUSPEND=1" : "SYSTEMD_HOME_SUSPEND=0");
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM environment variable $SYSTEMD_HOME_SUSPEND: @PAMERR@");
|
||||
@@ -911,6 +912,12 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
bool debug = false;
|
||||
int r;
|
||||
|
||||
r = dlopen_libpam(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
(void) dlopen_libintl(LOG_DEBUG); /* best-effort: messages won't be translated if this fails */
|
||||
|
||||
pam_log_setup();
|
||||
|
||||
if (parse_argv(pamh,
|
||||
@@ -921,7 +928,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
|
||||
pam_debug_syslog(pamh, debug, "pam-systemd-homed: closing session...");
|
||||
|
||||
r = pam_get_user(pamh, &username, NULL);
|
||||
r = sym_pam_get_user(pamh, &username, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
|
||||
if (isempty(username))
|
||||
@@ -954,7 +961,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, PAM_SESSION_ERR,
|
||||
"Failed to release user home: %s", bus_error_message(&error, r));
|
||||
|
||||
pam_syslog(pamh, LOG_NOTICE, "Not deactivating home directory of %s, as it is still used.", username);
|
||||
sym_pam_syslog(pamh, LOG_NOTICE, "Not deactivating home directory of %s, as it is still used.", username);
|
||||
}
|
||||
|
||||
return PAM_SUCCESS;
|
||||
@@ -976,6 +983,8 @@ _public_ PAM_EXTERN int pam_sm_acct_mgmt(
|
||||
if (r < 0)
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
(void) dlopen_libintl(LOG_DEBUG); /* best-effort: messages won't be translated if this fails */
|
||||
|
||||
pam_log_setup();
|
||||
|
||||
if (parse_env(pamh, &flags) < 0)
|
||||
@@ -1005,7 +1014,7 @@ _public_ PAM_EXTERN int pam_sm_acct_mgmt(
|
||||
switch (r) {
|
||||
|
||||
case -ESTALE:
|
||||
pam_syslog(pamh, LOG_WARNING, "User record for '%s' is newer than current system time, assuming incorrect system clock, allowing access.", ur->user_name);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "User record for '%s' is newer than current system time, assuming incorrect system clock, allowing access.", ur->user_name);
|
||||
break;
|
||||
|
||||
case -ENOLCK:
|
||||
@@ -1062,7 +1071,7 @@ _public_ PAM_EXTERN int pam_sm_acct_mgmt(
|
||||
|
||||
case -ESTALE:
|
||||
/* If the system clock is wrong, let's log but continue */
|
||||
pam_syslog(pamh, LOG_WARNING, "Couldn't check if password change is required, last change is in the future, system clock likely wrong.");
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Couldn't check if password change is required, last change is in the future, system clock likely wrong.");
|
||||
break;
|
||||
|
||||
case -EROFS:
|
||||
@@ -1095,6 +1104,8 @@ _public_ PAM_EXTERN int pam_sm_chauthtok(
|
||||
if (r < 0)
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
(void) dlopen_libintl(LOG_DEBUG); /* best-effort: messages won't be translated if this fails */
|
||||
|
||||
pam_log_setup();
|
||||
|
||||
if (parse_argv(pamh,
|
||||
@@ -1121,7 +1132,7 @@ _public_ PAM_EXTERN int pam_sm_chauthtok(
|
||||
/* No, it's not cached, then let's ask for the password and its verification, and cache
|
||||
* it. */
|
||||
|
||||
r = pam_get_authtok_noverify(pamh, &new_password, "New password: ");
|
||||
r = sym_pam_get_authtok_noverify(pamh, &new_password, "New password: ");
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get new password: @PAMERR@");
|
||||
|
||||
@@ -1130,7 +1141,7 @@ _public_ PAM_EXTERN int pam_sm_chauthtok(
|
||||
return PAM_AUTHTOK_ERR;
|
||||
}
|
||||
|
||||
r = pam_get_authtok_verify(pamh, &new_password, "new password: "); /* Lower case, since PAM prefixes 'Repeat' */
|
||||
r = sym_pam_get_authtok_verify(pamh, &new_password, "new password: "); /* Lower case, since PAM prefixes 'Repeat' */
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get password again: @PAMERR@");
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ executables += [
|
||||
'import-common.c',
|
||||
'qcow2-util.c',
|
||||
),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
libexec_template + {
|
||||
'name' : 'systemd-pull',
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
/* Force glibc's stdio.h to route sscanf/fscanf to the old __isoc99_* siblings (GLIBC_2.7) rather
|
||||
* than the newer __isoc23_* ones (GLIBC_2.38). The only behavioural difference is "0b" prefix
|
||||
* support in %i conversions, which we don't use. We include features.h first so the macro is set
|
||||
* to its normal value, then override it before stdio.h's body evaluates __GLIBC_USE(C23_STRTOL).
|
||||
*
|
||||
* The macro was named __GLIBC_USE_C2X_STRTOL on glibc 2.38–2.39 and renamed to the C23 spelling
|
||||
* in glibc 2.40; clear both so this override works across that range. */
|
||||
|
||||
#include <features.h>
|
||||
#undef __GLIBC_USE_C2X_STRTOL
|
||||
#define __GLIBC_USE_C2X_STRTOL 0
|
||||
#undef __GLIBC_USE_C23_STRTOL
|
||||
#define __GLIBC_USE_C23_STRTOL 0
|
||||
|
||||
#include_next <stdio.h> /* IWYU pragma: export */
|
||||
@@ -0,0 +1,17 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
/* Force glibc's stdlib.h to leave strtol/strtoul/strtoll/strtoull as their original GLIBC_2.2.5
|
||||
* symbols rather than redirect to __isoc23_* (GLIBC_2.38). The only behavioural difference is
|
||||
* "0b" prefix support in base 0/2 parsing, which we don't use.
|
||||
*
|
||||
* The macro was named __GLIBC_USE_C2X_STRTOL on glibc 2.38–2.39 and renamed to the C23 spelling
|
||||
* in glibc 2.40; clear both so this override works across that range. */
|
||||
|
||||
#include <features.h>
|
||||
#undef __GLIBC_USE_C2X_STRTOL
|
||||
#define __GLIBC_USE_C2X_STRTOL 0
|
||||
#undef __GLIBC_USE_C23_STRTOL
|
||||
#define __GLIBC_USE_C23_STRTOL 0
|
||||
|
||||
#include_next <stdlib.h> /* IWYU pragma: export */
|
||||
@@ -25,7 +25,6 @@ common_deps = [
|
||||
liblz4_cflags,
|
||||
libxz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
]
|
||||
|
||||
executables += [
|
||||
|
||||
@@ -72,7 +72,6 @@ executables += [
|
||||
libselinux_cflags,
|
||||
libxz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
libexec_template + {
|
||||
@@ -86,7 +85,6 @@ executables += [
|
||||
'public' : true,
|
||||
'sources' : files('cat.c'),
|
||||
'objects' : ['systemd-journald'],
|
||||
'dependencies' : [threads],
|
||||
},
|
||||
executable_template + {
|
||||
'name' : 'journalctl',
|
||||
@@ -94,11 +92,9 @@ executables += [
|
||||
'sources' : journalctl_sources,
|
||||
'link_with' : journalctl_link_with,
|
||||
'dependencies' : [
|
||||
libdl,
|
||||
liblz4_cflags,
|
||||
libxz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
journal_test_template + {
|
||||
@@ -123,7 +119,6 @@ executables += [
|
||||
liblz4_cflags,
|
||||
libselinux_cflags,
|
||||
libxz_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
journal_test_template + {
|
||||
|
||||
+46
-18
@@ -1,6 +1,7 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
@@ -35,21 +36,38 @@
|
||||
#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 shim resolves the libc symbol via dlsym(RTLD_DEFAULT) at DSO-load time using a constructor
|
||||
* and caches the result in a file-scope static. Constructors run single-threaded before main() and
|
||||
* before any signal handler can fire, so the cached pointer needs no atomics: subsequent reads from
|
||||
* any thread observe the value stored during init. Resolving eagerly also keeps dlsym() out of
|
||||
* contexts where it is not async-signal-safe (signal handlers, between fork() and exec()).
|
||||
*
|
||||
* 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. */
|
||||
* The asm barrier after dlsym() is load-bearing: without it, when LTO determines the cache store
|
||||
* is dead (because no caller of func##_shim survives DCE) the compiler is free to tail-call
|
||||
* dlsym() (jmp dlsym@plt). Under glibc, dlsym reads __builtin_return_address(0) to find its
|
||||
* caller's link map; with a tail call that read lands inside ld.so's call_init(), the resulting
|
||||
* link map has no l_scope, and _dl_lookup_symbol_x SIGSEGVs. Filed upstream in glibc by
|
||||
* https://sourceware.org/bugzilla/show_bug.cgi?id=34156. The barrier keeps us working on
|
||||
* unpatched libc.
|
||||
*
|
||||
* Each reference to `func` in the macro body is positioned as an operand of `#` or `##` so the
|
||||
* override headers (e.g. "#define openat2 openat2_shim") don't rewrite the token before pasting or
|
||||
* stringification. For the same reason the resolution logic isn't extracted into a helper macro —
|
||||
* passing `func` to a nested macro would expand it as a regular argument and re-trigger the
|
||||
* override.
|
||||
*
|
||||
* Defines a wrapper that calls the libc symbol if available at runtime, or falls back to the
|
||||
* corresponding direct syscall otherwise. Each parameter is passed as type, name pairs (flat). */
|
||||
#define DEFINE_SYSCALL_SHIM(func, ret, ...) \
|
||||
extern typeof(func##_shim) func##_libc_weak __asm__(#func) __attribute__((__weak__)); \
|
||||
static typeof(&func##_shim) func##_shim_cache; \
|
||||
__attribute__((constructor)) static void func##_shim_init(void) { \
|
||||
void *p = dlsym(RTLD_DEFAULT, #func); \
|
||||
__asm__ volatile("" ::: "memory"); \
|
||||
func##_shim_cache = (typeof(&func##_shim)) p; \
|
||||
} \
|
||||
ret func##_shim(_SHIM_DECL(__VA_ARGS__)) { \
|
||||
if (func##_libc_weak) \
|
||||
return func##_libc_weak(_SHIM_NAME(__VA_ARGS__)); \
|
||||
if (func##_shim_cache) \
|
||||
return func##_shim_cache(_SHIM_NAME(__VA_ARGS__)); \
|
||||
return syscall(__NR_##func, _SHIM_NAME(__VA_ARGS__)); \
|
||||
}
|
||||
|
||||
@@ -57,20 +75,30 @@
|
||||
* 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__)); \
|
||||
static typeof(&func##_shim) func##_shim_cache; \
|
||||
__attribute__((constructor)) static void func##_shim_init(void) { \
|
||||
void *p = dlsym(RTLD_DEFAULT, #func); \
|
||||
__asm__ volatile("" ::: "memory"); \
|
||||
func##_shim_cache = (typeof(&func##_shim)) p; \
|
||||
} \
|
||||
ret func##_shim(_SHIM_DECL(__VA_ARGS__)) { \
|
||||
if (func##_libc_weak) \
|
||||
return func##_libc_weak(_SHIM_NAME(__VA_ARGS__)); \
|
||||
if (func##_shim_cache) \
|
||||
return func##_shim_cache(_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__)); \
|
||||
static typeof(&func##_shim) func##_shim_cache; \
|
||||
__attribute__((constructor)) static void func##_shim_init(void) { \
|
||||
void *p = dlsym(RTLD_DEFAULT, #func); \
|
||||
__asm__ volatile("" ::: "memory"); \
|
||||
func##_shim_cache = (typeof(&func##_shim)) p; \
|
||||
} \
|
||||
ret func##_shim(_SHIM_DECL(__VA_ARGS__)) { \
|
||||
if (func##_libc_weak) \
|
||||
return func##_libc_weak(_SHIM_NAME(__VA_ARGS__)); \
|
||||
if (func##_shim_cache) \
|
||||
return func##_shim_cache(_SHIM_NAME(__VA_ARGS__)); \
|
||||
errno = ENOSYS; \
|
||||
return -1; \
|
||||
}
|
||||
|
||||
@@ -150,9 +150,7 @@ libsystemd_static = static_library(
|
||||
c_args : libsystemd_c_args,
|
||||
link_with : [libc_wrapper_static,
|
||||
libbasic_static],
|
||||
dependencies : [threads,
|
||||
libm,
|
||||
librt,
|
||||
dependencies : [libm,
|
||||
userspace],
|
||||
build_by_default : false)
|
||||
|
||||
@@ -203,51 +201,42 @@ simple_tests += files(
|
||||
libsystemd_tests += [
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-address.c'),
|
||||
'dependencies' : threads
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-benchmark.c'),
|
||||
'dependencies' : threads,
|
||||
'type' : 'manual',
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-chat.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-cleanup.c'),
|
||||
'dependencies' : [threads, libseccomp_cflags],
|
||||
'dependencies' : libseccomp_cflags,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-marshal.c'),
|
||||
'dependencies' : [
|
||||
libdbus,
|
||||
libgio,
|
||||
libglib,
|
||||
libgobject,
|
||||
libdbus_cflags,
|
||||
libgio_cflags,
|
||||
libglib_cflags,
|
||||
libgobject_cflags,
|
||||
libm,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-objects.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-peersockaddr.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-queue-ref-cycle.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-server.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-signature.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-track.c'),
|
||||
@@ -255,12 +244,11 @@ libsystemd_tests += [
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-bus/test-bus-watch-bind.c'),
|
||||
'dependencies' : threads,
|
||||
'timeout' : 120,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-device/test-sd-device.c'),
|
||||
'dependencies' : [threads, libmount_cflags],
|
||||
'dependencies' : libmount_cflags,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-event/test-event.c'),
|
||||
@@ -288,16 +276,13 @@ libsystemd_tests += [
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-resolve/test-resolve.c'),
|
||||
'dependencies' : threads,
|
||||
'timeout' : 120,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-varlink/test-varlink.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
{
|
||||
'sources' : files('sd-varlink/test-varlink-idl.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/* We make an exception here to our usual "include system headers first" rule because we need one of these
|
||||
* macros to disable a warning triggered by the glib headers. */
|
||||
#include "macro-fundamental.h"
|
||||
@@ -23,6 +21,7 @@ REENABLE_WARNING
|
||||
#include "bus-label.h"
|
||||
#include "bus-message.h"
|
||||
#include "bus-util.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "escape.h"
|
||||
#include "fd-util.h"
|
||||
#include "log.h"
|
||||
@@ -31,6 +30,40 @@ REENABLE_WARNING
|
||||
#include "stat-util.h"
|
||||
#include "tests.h"
|
||||
|
||||
#if HAVE_GLIB
|
||||
static void *glib_dl = NULL;
|
||||
static DLSYM_PROTOTYPE(g_dbus_message_new_from_blob) = NULL;
|
||||
static DLSYM_PROTOTYPE(g_dbus_message_print) = NULL;
|
||||
static DLSYM_PROTOTYPE(g_free) = NULL;
|
||||
static DLSYM_PROTOTYPE(g_object_unref) = NULL;
|
||||
|
||||
static int dlopen_glib(void) {
|
||||
return dlopen_many_sym_or_warn(
|
||||
&glib_dl, "libgio-2.0.so.0", LOG_DEBUG,
|
||||
DLSYM_ARG(g_dbus_message_new_from_blob),
|
||||
DLSYM_ARG(g_dbus_message_print),
|
||||
DLSYM_ARG(g_free),
|
||||
DLSYM_ARG(g_object_unref));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAVE_DBUS
|
||||
static void *libdbus_dl = NULL;
|
||||
static DLSYM_PROTOTYPE(dbus_error_init) = NULL;
|
||||
static DLSYM_PROTOTYPE(dbus_error_free) = NULL;
|
||||
static DLSYM_PROTOTYPE(dbus_message_demarshal) = NULL;
|
||||
static DLSYM_PROTOTYPE(dbus_message_unref) = NULL;
|
||||
|
||||
static int dlopen_libdbus(void) {
|
||||
return dlopen_many_sym_or_warn(
|
||||
&libdbus_dl, "libdbus-1.so.3", LOG_DEBUG,
|
||||
DLSYM_ARG(dbus_error_init),
|
||||
DLSYM_ARG(dbus_error_free),
|
||||
DLSYM_ARG(dbus_message_demarshal),
|
||||
DLSYM_ARG(dbus_message_unref));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void test_bus_path_encode_unique(void) {
|
||||
_cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
|
||||
|
||||
@@ -322,39 +355,32 @@ int main(int argc, char *argv[]) {
|
||||
log_info("message size = %zu, contents =\n%s", sz, h);
|
||||
|
||||
#if HAVE_GLIB
|
||||
/* Work-around for asan bug. See c8d980a3e962aba2ea3a4cedf75fa94890a6d746. */
|
||||
#if !HAS_FEATURE_ADDRESS_SANITIZER
|
||||
{
|
||||
if (dlopen_glib() >= 0) {
|
||||
GDBusMessage *g;
|
||||
char *p;
|
||||
|
||||
#if !defined(GLIB_VERSION_2_36)
|
||||
g_type_init();
|
||||
#endif
|
||||
|
||||
g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
|
||||
p = g_dbus_message_print(g, 0);
|
||||
g = sym_g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
|
||||
p = sym_g_dbus_message_print(g, 0);
|
||||
log_info("%s", p);
|
||||
g_free(p);
|
||||
g_object_unref(g);
|
||||
sym_g_free(p);
|
||||
sym_g_object_unref(g);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_DBUS
|
||||
{
|
||||
if (dlopen_libdbus() >= 0) {
|
||||
DBusMessage *w;
|
||||
DBusError error;
|
||||
|
||||
dbus_error_init(&error);
|
||||
sym_dbus_error_init(&error);
|
||||
|
||||
w = dbus_message_demarshal(buffer, sz, &error);
|
||||
w = sym_dbus_message_demarshal(buffer, sz, &error);
|
||||
if (!w)
|
||||
log_error("%s", error.message);
|
||||
else
|
||||
dbus_message_unref(w);
|
||||
sym_dbus_message_unref(w);
|
||||
|
||||
dbus_error_free(&error);
|
||||
sym_dbus_error_free(&error);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -451,7 +477,7 @@ int main(int argc, char *argv[]) {
|
||||
assert_se(r > 0);
|
||||
assert_se(streq(x, "foo"));
|
||||
assert_se(u64 == 815ULL);
|
||||
assert_se(fabs(dbl - 47.0) < 0.1);
|
||||
assert_se(ABS(dbl - 47.0) < 0.1);
|
||||
assert_se(streq(y, "/"));
|
||||
|
||||
r = sd_bus_message_peek_type(m, NULL, NULL);
|
||||
|
||||
@@ -61,8 +61,8 @@ static void test_tokenizer_one(const char *data, ...) {
|
||||
|
||||
d = va_arg(ap, double);
|
||||
|
||||
assert_se(fabs(d - v.real) < 1e-10 ||
|
||||
fabs((d - v.real) / v.real) < 1e-10);
|
||||
assert_se(ABS(d - v.real) < 1e-10 ||
|
||||
ABS((d - v.real) / v.real) < 1e-10);
|
||||
|
||||
} else if (t == JSON_TOKEN_INTEGER) {
|
||||
int64_t i;
|
||||
@@ -243,7 +243,7 @@ static void test_2(sd_json_variant *v) {
|
||||
|
||||
/* has thisisaverylongproperty */
|
||||
p = sd_json_variant_by_key(v, "thisisaverylongproperty");
|
||||
assert_se(p && sd_json_variant_type(p) == SD_JSON_VARIANT_REAL && fabs(sd_json_variant_real(p) - 1.27) < 0.001);
|
||||
assert_se(p && sd_json_variant_type(p) == SD_JSON_VARIANT_REAL && ABS(sd_json_variant_real(p) - 1.27) < 0.001);
|
||||
}
|
||||
|
||||
static void test_zeroes(sd_json_variant *v) {
|
||||
@@ -753,14 +753,14 @@ static void test_float_match(sd_json_variant *v) {
|
||||
assert_se(sd_json_variant_is_array(v));
|
||||
assert_se(sd_json_variant_elements(v) == 11);
|
||||
assert_se(!iszero_safe(sd_json_variant_real(sd_json_variant_by_index(v, 0))));
|
||||
assert_se(fabs(1.0 - (DBL_MIN / sd_json_variant_real(sd_json_variant_by_index(v, 0)))) <= delta);
|
||||
assert_se(ABS(1.0 - (DBL_MIN / sd_json_variant_real(sd_json_variant_by_index(v, 0)))) <= delta);
|
||||
assert_se(!iszero_safe(sd_json_variant_real(sd_json_variant_by_index(v, 1))));
|
||||
assert_se(fabs(1.0 - (DBL_MAX / sd_json_variant_real(sd_json_variant_by_index(v, 1)))) <= delta);
|
||||
assert_se(ABS(1.0 - (DBL_MAX / sd_json_variant_real(sd_json_variant_by_index(v, 1)))) <= delta);
|
||||
assert_se(sd_json_variant_is_null(sd_json_variant_by_index(v, 2))); /* nan is not supported by json → null */
|
||||
assert_se(sd_json_variant_is_null(sd_json_variant_by_index(v, 3))); /* +inf is not supported by json → null */
|
||||
assert_se(sd_json_variant_is_null(sd_json_variant_by_index(v, 4))); /* -inf is not supported by json → null */
|
||||
assert_se(sd_json_variant_is_null(sd_json_variant_by_index(v, 5)) ||
|
||||
fabs(1.0 - (HUGE_VAL / sd_json_variant_real(sd_json_variant_by_index(v, 5)))) <= delta); /* HUGE_VAL might be +inf, but might also be something else */
|
||||
ABS(1.0 - (HUGE_VAL / sd_json_variant_real(sd_json_variant_by_index(v, 5)))) <= delta); /* HUGE_VAL might be +inf, but might also be something else */
|
||||
assert_se(sd_json_variant_is_real(sd_json_variant_by_index(v, 6)) &&
|
||||
sd_json_variant_is_integer(sd_json_variant_by_index(v, 6)) &&
|
||||
sd_json_variant_integer(sd_json_variant_by_index(v, 6)) == 0);
|
||||
@@ -773,11 +773,11 @@ static void test_float_match(sd_json_variant *v) {
|
||||
assert_se(sd_json_variant_is_real(sd_json_variant_by_index(v, 9)) &&
|
||||
!sd_json_variant_is_integer(sd_json_variant_by_index(v, 9)));
|
||||
assert_se(!iszero_safe(sd_json_variant_real(sd_json_variant_by_index(v, 9))));
|
||||
assert_se(fabs(1.0 - (DBL_MIN / 2 / sd_json_variant_real(sd_json_variant_by_index(v, 9)))) <= delta);
|
||||
assert_se(ABS(1.0 - (DBL_MIN / 2 / sd_json_variant_real(sd_json_variant_by_index(v, 9)))) <= delta);
|
||||
assert_se(sd_json_variant_is_real(sd_json_variant_by_index(v, 10)) &&
|
||||
!sd_json_variant_is_integer(sd_json_variant_by_index(v, 10)));
|
||||
assert_se(!iszero_safe(sd_json_variant_real(sd_json_variant_by_index(v, 10))));
|
||||
assert_se(fabs(1.0 - (-DBL_MIN / 2 / sd_json_variant_real(sd_json_variant_by_index(v, 10)))) <= delta);
|
||||
assert_se(ABS(1.0 - (-DBL_MIN / 2 / sd_json_variant_real(sd_json_variant_by_index(v, 10)))) <= delta);
|
||||
}
|
||||
|
||||
TEST(float) {
|
||||
@@ -1143,8 +1143,8 @@ TEST(json_dispatch_double) {
|
||||
/* flags= */ 0,
|
||||
&data) >= 0);
|
||||
|
||||
assert_se(fabs(data.x1 - 0.5) < 0.01);
|
||||
assert_se(fabs(data.x2 + 0.5) < 0.01);
|
||||
assert_se(ABS(data.x1 - 0.5) < 0.01);
|
||||
assert_se(ABS(data.x2 + 0.5) < 0.01);
|
||||
assert_se(isinf(data.x3));
|
||||
assert_se(data.x3 > 0);
|
||||
assert_se(isinf(data.x4));
|
||||
|
||||
@@ -16,5 +16,4 @@ Name: libudev
|
||||
Description: Library to access udev device information
|
||||
Version: {{PROJECT_VERSION}}
|
||||
Libs: -L${libdir} -ludev
|
||||
Libs.private: -lrt -pthread
|
||||
Cflags: -I${includedir}
|
||||
|
||||
@@ -18,7 +18,6 @@ localectl_sources = files('localectl.c')
|
||||
# specify where the headers are.
|
||||
if conf.get('HAVE_XKBCOMMON') == 1
|
||||
libxkbcommon_deps = [
|
||||
libdl,
|
||||
libxkbcommon_cflags,
|
||||
]
|
||||
else
|
||||
|
||||
@@ -48,9 +48,6 @@ executables += [
|
||||
'dbus' : true,
|
||||
'sources' : systemd_logind_sources,
|
||||
'extract' : systemd_logind_extract_sources,
|
||||
'dependencies' : [
|
||||
threads,
|
||||
],
|
||||
},
|
||||
executable_template + {
|
||||
'name' : 'loginctl',
|
||||
@@ -60,7 +57,6 @@ executables += [
|
||||
liblz4_cflags,
|
||||
libxz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
executable_template + {
|
||||
@@ -79,7 +75,6 @@ executables += [
|
||||
test_template + {
|
||||
'sources' : files('test-login-tables.c'),
|
||||
'objects' : ['systemd-logind'],
|
||||
'dependencies' : threads,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-session-properties.c'),
|
||||
|
||||
+51
-49
@@ -3,7 +3,6 @@
|
||||
#include <endian.h>
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
#include <security/pam_misc.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysmacros.h>
|
||||
@@ -88,7 +87,7 @@ static int parse_caps(
|
||||
|
||||
c = capability_from_name(s);
|
||||
if (c < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Unknown capability, ignoring: %s", s);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Unknown capability, ignoring: %s", s);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -146,7 +145,7 @@ static int parse_argv(
|
||||
} else if ((p = startswith(argv[i], "area="))) {
|
||||
|
||||
if (!isempty(p) && !filename_is_valid(p))
|
||||
pam_syslog(pamh, LOG_WARNING, "Area name specified among PAM module parameters is not valid, ignoring: %s", p);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Area name specified among PAM module parameters is not valid, ignoring: %s", p);
|
||||
else if (area)
|
||||
*area = p;
|
||||
|
||||
@@ -157,22 +156,22 @@ static int parse_argv(
|
||||
} else if ((p = startswith(argv[i], "debug="))) {
|
||||
r = parse_boolean(p);
|
||||
if (r < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", p);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse debug= argument, ignoring: %s", p);
|
||||
else if (debug)
|
||||
*debug = r;
|
||||
|
||||
} else if ((p = startswith(argv[i], "default-capability-bounding-set="))) {
|
||||
r = parse_caps(pamh, p, default_capability_bounding_set);
|
||||
if (r < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-bounding-set= argument, ignoring: %s", p);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-bounding-set= argument, ignoring: %s", p);
|
||||
|
||||
} else if ((p = startswith(argv[i], "default-capability-ambient-set="))) {
|
||||
r = parse_caps(pamh, p, default_capability_ambient_set);
|
||||
if (r < 0)
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-ambient-set= argument, ignoring: %s", p);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse default-capability-ambient-set= argument, ignoring: %s", p);
|
||||
|
||||
} else
|
||||
pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -184,7 +183,7 @@ static int acquire_user_record(pam_handle_t *pamh, UserRecord **ret_record) {
|
||||
assert(pamh);
|
||||
|
||||
const char *username = NULL;
|
||||
r = pam_get_user(pamh, &username, NULL);
|
||||
r = sym_pam_get_user(pamh, &username, NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get user name: @PAMERR@");
|
||||
if (isempty(username))
|
||||
@@ -198,7 +197,7 @@ static int acquire_user_record(pam_handle_t *pamh, UserRecord **ret_record) {
|
||||
|
||||
_cleanup_(user_record_unrefp) UserRecord *ur = NULL;
|
||||
const char *json = NULL;
|
||||
r = pam_get_data(pamh, field, (const void**) &json);
|
||||
r = sym_pam_get_data(pamh, field, (const void**) &json);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM user record data: @PAMERR@");
|
||||
if (r == PAM_SUCCESS && json) {
|
||||
@@ -240,7 +239,7 @@ static int acquire_user_record(pam_handle_t *pamh, UserRecord **ret_record) {
|
||||
return pam_syslog_errno(pamh, LOG_ERR, r, "Failed to format user JSON: %m");
|
||||
|
||||
/* And cache it for everyone else */
|
||||
r = pam_set_data(pamh, field, formatted, pam_cleanup_free);
|
||||
r = sym_pam_set_data(pamh, field, formatted, pam_cleanup_free);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM user record data '%s': @PAMERR@", field);
|
||||
@@ -382,7 +381,7 @@ static int append_session_memory_max(pam_handle_t *pamh, sd_bus_message *m, cons
|
||||
uint64_t val;
|
||||
r = parse_size(limit, 1024, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.memory_max, ignoring: %s", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.memory_max, ignoring: %s", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -402,7 +401,7 @@ static int append_session_runtime_max_sec(pam_handle_t *pamh, sd_bus_message *m,
|
||||
usec_t val;
|
||||
r = parse_sec(limit, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.runtime_max_sec: %s, ignoring.", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.runtime_max_sec: %s, ignoring.", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -422,7 +421,7 @@ static int append_session_tasks_max(pam_handle_t *pamh, sd_bus_message *m, const
|
||||
uint64_t val;
|
||||
r = safe_atou64(limit, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.tasks_max, ignoring: %s", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.tasks_max, ignoring: %s", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -441,7 +440,7 @@ static int append_session_cpu_weight(pam_handle_t *pamh, sd_bus_message *m, cons
|
||||
uint64_t val;
|
||||
r = cg_cpu_weight_parse(limit, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.cpu_weight, ignoring: %s", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.cpu_weight, ignoring: %s", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -460,7 +459,7 @@ static int append_session_io_weight(pam_handle_t *pamh, sd_bus_message *m, const
|
||||
uint64_t val;
|
||||
r = cg_weight_parse(limit, &val);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.io_weight, ignoring: %s", limit);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Failed to parse systemd.io_weight, ignoring: %s", limit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -479,7 +478,7 @@ static const char* getenv_harder(pam_handle_t *pamh, const char *key, const char
|
||||
* PAM services don't have to be reworked to set systemd-specific properties, but these properties
|
||||
* can still be set from the unit file Environment= block. */
|
||||
|
||||
v = pam_getenv(pamh, key);
|
||||
v = sym_pam_getenv(pamh, key);
|
||||
if (!isempty(v))
|
||||
return v;
|
||||
|
||||
@@ -507,9 +506,9 @@ static bool getenv_harder_bool(pam_handle_t *pamh, const char *key, bool fallbac
|
||||
|
||||
r = parse_boolean(v);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING,
|
||||
"Failed to parse environment variable value '%s' of '%s', falling back to using '%s'.",
|
||||
v, key, true_false(fallback));
|
||||
sym_pam_syslog(pamh, LOG_WARNING,
|
||||
"Failed to parse environment variable value '%s' of '%s', falling back to using '%s'.",
|
||||
v, key, true_false(fallback));
|
||||
return fallback;
|
||||
}
|
||||
|
||||
@@ -529,9 +528,9 @@ static uint32_t getenv_harder_uint32(pam_handle_t *pamh, const char *key, uint32
|
||||
uint32_t u;
|
||||
r = safe_atou32(v, &u);
|
||||
if (r < 0) {
|
||||
pam_syslog(pamh, LOG_WARNING,
|
||||
"Failed to parse environment variable value '%s' of '%s' as unsigned integer, falling back to using %" PRIu32 ".",
|
||||
v, key, fallback);
|
||||
sym_pam_syslog(pamh, LOG_WARNING,
|
||||
"Failed to parse environment variable value '%s' of '%s' as unsigned integer, falling back to using %" PRIu32 ".",
|
||||
v, key, fallback);
|
||||
return fallback;
|
||||
}
|
||||
|
||||
@@ -548,14 +547,14 @@ static int update_environment(pam_handle_t *pamh, const char *key, const char *v
|
||||
* about errors. */
|
||||
|
||||
if (isempty(value)) {
|
||||
/* Unset the variable if set. Note that pam_putenv() would log nastily behind our back if we
|
||||
/* Unset the variable if set. Note that sym_pam_putenv() would log nastily behind our back if we
|
||||
* call it without the variable actually being set. Hence we check explicitly if it's set
|
||||
* before. */
|
||||
|
||||
if (!pam_getenv(pamh, key))
|
||||
if (!sym_pam_getenv(pamh, key))
|
||||
return PAM_SUCCESS;
|
||||
|
||||
r = pam_putenv(pamh, key);
|
||||
r = sym_pam_putenv(pamh, key);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_BAD_ITEM))
|
||||
return pam_syslog_pam_error(pamh, LOG_WARNING, r,
|
||||
"Failed to unset %s environment variable: @PAMERR@", key);
|
||||
@@ -563,7 +562,7 @@ static int update_environment(pam_handle_t *pamh, const char *key, const char *v
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
r = pam_misc_setenv(pamh, key, value, /* readonly= */ false);
|
||||
r = pam_putenv_assign(pamh, key, value);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set environment variable %s: @PAMERR@", key);
|
||||
@@ -588,7 +587,7 @@ static int propagate_credential_to_environment(pam_handle_t *pamh, bool debug, c
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
r = pam_misc_setenv(pamh, varname, value, 0);
|
||||
r = pam_putenv_assign(pamh, varname, value);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set environment variable %s: @PAMERR@", varname);
|
||||
@@ -610,7 +609,7 @@ static bool validate_runtime_directory(pam_handle_t *pamh, const char *path, uid
|
||||
* otherwise we might end up setting $XDG_RUNTIME_DIR to some directory owned by the wrong user. */
|
||||
|
||||
if (!path_is_absolute(path)) {
|
||||
pam_syslog(pamh, LOG_ERR, "Provided runtime directory '%s' is not absolute.", path);
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Provided runtime directory '%s' is not absolute.", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -620,19 +619,19 @@ static bool validate_runtime_directory(pam_handle_t *pamh, const char *path, uid
|
||||
}
|
||||
|
||||
if (!S_ISDIR(st.st_mode)) {
|
||||
pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path);
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (st.st_uid != uid) {
|
||||
pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid);
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
pam_syslog(pamh, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order.");
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -642,7 +641,7 @@ static int pam_putenv_and_log(pam_handle_t *pamh, const char *e, bool debug) {
|
||||
assert(pamh);
|
||||
assert(e);
|
||||
|
||||
r = pam_putenv(pamh, e);
|
||||
r = sym_pam_putenv(pamh, e);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM environment variable %s: @PAMERR@", e);
|
||||
@@ -992,7 +991,7 @@ static void session_context_mangle(
|
||||
c->area = ur->default_area;
|
||||
|
||||
if (!isempty(c->area) && !filename_is_valid(c->area)) {
|
||||
pam_syslog(pamh, LOG_WARNING, "Specified area '%s' is not a valid filename, ignoring area request.", c->area);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Specified area '%s' is not a valid filename, ignoring area request.", c->area);
|
||||
c->area = NULL;
|
||||
}
|
||||
|
||||
@@ -1048,7 +1047,7 @@ static void session_context_mangle(
|
||||
if (streq(c->class, "user"))
|
||||
c->class = "user-incomplete";
|
||||
else
|
||||
pam_syslog(pamh, LOG_WARNING, "PAM session of class '%s' is incomplete, which is not supported, ignoring.", c->class);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "PAM session of class '%s' is incomplete, which is not supported, ignoring.", c->class);
|
||||
}
|
||||
|
||||
c->remote = !isempty(c->remote_host) && !is_localhost(c->remote_host);
|
||||
@@ -1253,8 +1252,7 @@ static int register_session(
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
pam_syslog(pamh, LOG_ERR,
|
||||
"Failed to create session: %s", bus_error_message(&error, r));
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Failed to create session: %s", bus_error_message(&error, r));
|
||||
return PAM_SESSION_ERR;
|
||||
}
|
||||
|
||||
@@ -1282,7 +1280,7 @@ static int register_session(
|
||||
if (fd < 0)
|
||||
return pam_syslog_errno(pamh, LOG_ERR, errno, "Failed to dup session fd: %m");
|
||||
|
||||
r = pam_set_data(pamh, "systemd.session-fd", FD_TO_PTR(fd), NULL);
|
||||
r = sym_pam_set_data(pamh, "systemd.session-fd", FD_TO_PTR(fd), NULL);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to install session fd: @PAMERR@");
|
||||
TAKE_FD(fd);
|
||||
@@ -1580,7 +1578,7 @@ static int setup_environment(
|
||||
pam_syslog_errno(pamh, LOG_WARNING, r, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory: %m", j, area);
|
||||
|
||||
/* Also tell the user directly at login, but a bit more vague */
|
||||
pam_info(pamh, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory.", j, area);
|
||||
sym_pam_info(pamh, "Path '%s' of requested user area '%s' is not accessible, reverting to regular home directory.", j, area);
|
||||
area = NULL;
|
||||
} else {
|
||||
/* Validate that the target is definitely owned by user */
|
||||
@@ -1589,10 +1587,10 @@ static int setup_environment(
|
||||
return pam_syslog_errno(pamh, LOG_ERR, errno, "Unable to fstat() target area directory '%s': %m", ha);
|
||||
|
||||
if (st.st_uid != ur->uid) {
|
||||
pam_syslog(pamh, LOG_ERR, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
|
||||
sym_pam_syslog(pamh, LOG_ERR, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
|
||||
|
||||
/* Also tell the user directly at login. */
|
||||
pam_info(pamh, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
|
||||
sym_pam_info(pamh, "Path '%s' of requested user area '%s' is not owned by user, reverting to regular home directory.", ha, area);
|
||||
area = NULL;
|
||||
} else {
|
||||
/* All good, now make a copy of the area string, since we quite likely are
|
||||
@@ -1631,13 +1629,13 @@ static int open_osc_context(pam_handle_t *pamh, const char *session_type, UserRe
|
||||
if (!streq_ptr(session_type, "tty"))
|
||||
return PAM_SUCCESS;
|
||||
|
||||
const char *e = pam_getenv(pamh, "TERM");
|
||||
const char *e = sym_pam_getenv(pamh, "TERM");
|
||||
if (!e)
|
||||
e = getenv("TERM");
|
||||
if (streq_ptr(e, "dumb"))
|
||||
return PAM_SUCCESS;
|
||||
|
||||
/* NB: we output directly to stdout, instead of going via pam_info() or so, because that's too
|
||||
/* NB: we output directly to stdout, instead of going via sym_pam_info() or so, because that's too
|
||||
* high-level for us, as it suffixes the output with a newline, expecting a full blown text message
|
||||
* as prompt string, not just an ANSI sequence. Note that PAM's conv_misc() actually goes to stdout
|
||||
* anyway, hence let's do so here too, but only after careful validation. */
|
||||
@@ -1657,7 +1655,7 @@ static int open_osc_context(pam_handle_t *pamh, const char *session_type, UserRe
|
||||
sd_id128_t osc_id;
|
||||
r = osc_context_open_session(
|
||||
ur->user_name,
|
||||
pam_getenv(pamh, "XDG_SESSION_ID"),
|
||||
sym_pam_getenv(pamh, "XDG_SESSION_ID"),
|
||||
&osc,
|
||||
&osc_id);
|
||||
if (r < 0)
|
||||
@@ -1672,7 +1670,7 @@ static int open_osc_context(pam_handle_t *pamh, const char *session_type, UserRe
|
||||
if (!osc_id_copy)
|
||||
return pam_log_oom(pamh);
|
||||
|
||||
r = pam_set_data(pamh, "systemd.osc-context-id", osc_id_copy, pam_cleanup_free);
|
||||
r = sym_pam_set_data(pamh, "systemd.osc-context-id", osc_id_copy, pam_cleanup_free);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM OSC sequence ID data: @PAMERR@");
|
||||
@@ -1680,7 +1678,7 @@ static int open_osc_context(pam_handle_t *pamh, const char *session_type, UserRe
|
||||
TAKE_PTR(osc_id_copy);
|
||||
|
||||
if (tty_opath_fd >= 0) {
|
||||
r = pam_set_data(pamh, "systemd.osc-context-fd", FD_TO_PTR(tty_opath_fd), pam_cleanup_close);
|
||||
r = sym_pam_set_data(pamh, "systemd.osc-context-fd", FD_TO_PTR(tty_opath_fd), pam_cleanup_close);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r,
|
||||
"Failed to set PAM OSC sequence fd data: @PAMERR@");
|
||||
@@ -1698,7 +1696,7 @@ static int close_osc_context(pam_handle_t *pamh, bool debug) {
|
||||
|
||||
const void *p;
|
||||
int tty_opath_fd = -EBADF;
|
||||
r = pam_get_data(pamh, "systemd.osc-context-fd", &p);
|
||||
r = sym_pam_get_data(pamh, "systemd.osc-context-fd", &p);
|
||||
if (r == PAM_SUCCESS)
|
||||
tty_opath_fd = PTR_TO_FD(p);
|
||||
else if (r != PAM_NO_MODULE_DATA)
|
||||
@@ -1707,7 +1705,7 @@ static int close_osc_context(pam_handle_t *pamh, bool debug) {
|
||||
return PAM_SUCCESS;
|
||||
|
||||
const sd_id128_t *osc_id = NULL;
|
||||
r = pam_get_data(pamh, "systemd.osc-context-id", (const void**) &osc_id);
|
||||
r = sym_pam_get_data(pamh, "systemd.osc-context-id", (const void**) &osc_id);
|
||||
if (!IN_SET(r, PAM_SUCCESS, PAM_NO_MODULE_DATA))
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to get PAM OSC context id data: @PAMERR@");
|
||||
if (!osc_id)
|
||||
@@ -1721,7 +1719,7 @@ static int close_osc_context(pam_handle_t *pamh, bool debug) {
|
||||
}
|
||||
|
||||
/* /bin/login calls us with fds 0, 1, 2 closed, which is just weird. Let's step outside of that
|
||||
* range, just in case pam_syslog() or so logs to stderr */
|
||||
* range, just in case sym_pam_syslog() or so logs to stderr */
|
||||
fd = fd_move_above_stdio(fd);
|
||||
|
||||
/* Safety check, let's verify this is a valid TTY we just opened */
|
||||
@@ -1849,6 +1847,10 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
|
||||
assert(pamh);
|
||||
|
||||
r = dlopen_libpam(LOG_DEBUG);
|
||||
if (r < 0)
|
||||
return PAM_SERVICE_ERR;
|
||||
|
||||
pam_log_setup();
|
||||
|
||||
if (parse_argv(pamh,
|
||||
@@ -1866,7 +1868,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
|
||||
|
||||
(void) close_osc_context(pamh, debug);
|
||||
|
||||
id = pam_getenv(pamh, "XDG_SESSION_ID");
|
||||
id = sym_pam_getenv(pamh, "XDG_SESSION_ID");
|
||||
if (id) {
|
||||
_cleanup_(sd_varlink_unrefp) sd_varlink *vl = NULL;
|
||||
bool done = false;
|
||||
|
||||
@@ -41,7 +41,7 @@ _public_ PAM_EXTERN int pam_sm_authenticate(
|
||||
else if (streq(argv[i], "debug"))
|
||||
debug = true;
|
||||
else
|
||||
pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
sym_pam_syslog(pamh, LOG_WARNING, "Unknown parameter '%s', ignoring.", argv[i]);
|
||||
}
|
||||
|
||||
pam_debug_syslog(pamh, debug, "pam-systemd-loadkey: initializing...");
|
||||
@@ -81,7 +81,7 @@ _public_ PAM_EXTERN int pam_sm_authenticate(
|
||||
} else if (passwords_len > 1)
|
||||
pam_debug_syslog(pamh, debug, "Multiple passwords found in the key. Using the last one.");
|
||||
|
||||
r = pam_set_item(pamh, PAM_AUTHTOK, passwords[passwords_len - 1]);
|
||||
r = sym_pam_set_item(pamh, PAM_AUTHTOK, passwords[passwords_len - 1]);
|
||||
if (r != PAM_SUCCESS)
|
||||
return pam_syslog_pam_error(pamh, LOG_ERR, r, "Failed to set PAM auth token: @PAMERR@");
|
||||
|
||||
|
||||
@@ -36,13 +36,11 @@ executables += [
|
||||
liblz4_cflags,
|
||||
libxz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-machine-tables.c'),
|
||||
'objects' : ['systemd-machined'],
|
||||
'dependencies': threads,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -188,7 +188,6 @@ network_fuzz_template = fuzz_template + {
|
||||
libsystemd_network,
|
||||
],
|
||||
'objects' : ['systemd-networkd'],
|
||||
'dependencies' : threads,
|
||||
'include_directories' : network_includes,
|
||||
}
|
||||
|
||||
@@ -204,7 +203,6 @@ executables += [
|
||||
libsystemd_network,
|
||||
networkd_link_with,
|
||||
],
|
||||
'dependencies' : threads,
|
||||
'bpf_programs': [
|
||||
'sysctl-monitor',
|
||||
]
|
||||
@@ -240,11 +238,9 @@ executables += [
|
||||
},
|
||||
network_test_template + {
|
||||
'sources' : files('test-network-tables.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
network_test_template + {
|
||||
'sources' : files('test-network.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
network_test_template + {
|
||||
'sources' : files('test-networkd-address.c'),
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "sd-messages.h"
|
||||
|
||||
#include "af-list.h"
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "conf-parser.h"
|
||||
#include "alloc-util.h"
|
||||
#include "cgroup-util.h"
|
||||
|
||||
@@ -24,13 +24,11 @@ executables += [
|
||||
'name' : 'systemd-nsresourced',
|
||||
'sources' : systemd_nsresourced_sources,
|
||||
'extract' : systemd_nsresourced_extract_sources,
|
||||
'dependencies' : threads,
|
||||
'bpf_programs': ['userns-restrict'],
|
||||
},
|
||||
libexec_template + {
|
||||
'name' : 'systemd-nsresourcework',
|
||||
'sources' : systemd_nsresourcework_sources,
|
||||
'dependencies' : threads,
|
||||
'objects' : ['systemd-nsresourced'],
|
||||
'bpf_programs': ['userns-restrict'],
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
#include "sd-daemon.h"
|
||||
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#if HAVE_VMLINUX_H
|
||||
#include "bpf-link.h"
|
||||
#include "userns-restrict-skel.h"
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "userns-restrict-skel.h"
|
||||
#endif
|
||||
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "bpf-link.h"
|
||||
#include "fd-util.h"
|
||||
#include "log.h"
|
||||
|
||||
@@ -32,7 +32,6 @@ executables += [
|
||||
libcryptsetup_cflags,
|
||||
libmount_cflags,
|
||||
libselinux_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
executable_template + {
|
||||
@@ -40,7 +39,6 @@ executables += [
|
||||
'public' : true,
|
||||
'sources' : files('portablectl.c'),
|
||||
'link_with' : portabled_link_with,
|
||||
'dependencies' : threads,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ executables += [
|
||||
liblz4_cflags,
|
||||
libxz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -17,7 +17,6 @@ executables += [
|
||||
libfdisk_cflags,
|
||||
libmount_cflags,
|
||||
libopenssl_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
executable_template + {
|
||||
@@ -35,7 +34,6 @@ executables += [
|
||||
libfdisk_cflags,
|
||||
libmount_cflags,
|
||||
libopenssl_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -72,7 +72,6 @@ resolve_common_template = {
|
||||
libidn2_cflags,
|
||||
libopenssl_cflags,
|
||||
libm,
|
||||
threads,
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <bpf/libbpf.h>
|
||||
|
||||
/* libbpf has been moving quickly.
|
||||
* They added new symbols in the 0.x versions and shortly after removed
|
||||
* deprecated symbols in 1.0.
|
||||
* We only need bpf_map_create and libbpf_probe_bpf_prog_type so we work
|
||||
* around the incompatibility here by:
|
||||
* - declaring both symbols, and looking for either depending on the libbpf
|
||||
* so version we found
|
||||
* - having helpers that automatically use the appropriate version behind the
|
||||
* new API for easy cleanup later
|
||||
*
|
||||
* The advantage of doing this instead of only looking for the symbols declared at
|
||||
* compile time is that we can then load either the old or the new symbols at runtime
|
||||
* regardless of the version we were compiled with */
|
||||
|
||||
/* declare the struct for libbpf <= 0.6.0 -- it causes no harm on newer versions */
|
||||
struct bpf_map_create_opts;
|
||||
|
||||
/* new symbols available from 0.7.0.
|
||||
* We need the symbols here:
|
||||
* - after bpf_map_create_opts struct has been defined for older libbpf
|
||||
* - before the compat static inline helpers that use them.
|
||||
* When removing this file move these back to bpf-dlopen.h */
|
||||
extern int (*sym_bpf_map_create)(enum bpf_map_type, const char *, __u32, __u32, __u32, const struct bpf_map_create_opts *);
|
||||
extern struct bpf_map* (*sym_bpf_object__next_map)(const struct bpf_object *obj, const struct bpf_map *map);
|
||||
|
||||
/* compat symbols removed in libbpf 1.0 */
|
||||
extern int (*sym_bpf_create_map)(enum bpf_map_type, int key_size, int value_size, int max_entries, __u32 map_flags);
|
||||
|
||||
/* helpers to use the available variant behind new API */
|
||||
static inline int compat_bpf_map_create(
|
||||
enum bpf_map_type map_type,
|
||||
const char *map_name,
|
||||
__u32 key_size,
|
||||
__u32 value_size,
|
||||
__u32 max_entries,
|
||||
const struct bpf_map_create_opts *opts) {
|
||||
|
||||
if (sym_bpf_map_create)
|
||||
return sym_bpf_map_create(map_type, map_name, key_size,
|
||||
value_size, max_entries, opts);
|
||||
|
||||
return sym_bpf_create_map(map_type, key_size, value_size, max_entries,
|
||||
0 /* opts->map_flags, but opts is always NULL for us so skip build dependency on the type */);
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-dlopen.h"
|
||||
|
||||
#include "bpf-dlopen.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "log.h"
|
||||
|
||||
#if HAVE_LIBBPF
|
||||
|
||||
/* libbpf changed types of function prototypes around, so we need to disable some type checking for older
|
||||
* libbpf. We consider everything older than 0.7 too old for accurate type checks. */
|
||||
#if defined(__LIBBPF_CURRENT_VERSION_GEQ)
|
||||
#if __LIBBPF_CURRENT_VERSION_GEQ(0, 7)
|
||||
#define MODERN_LIBBPF 1
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(MODERN_LIBBPF)
|
||||
#define MODERN_LIBBPF 0
|
||||
#endif
|
||||
|
||||
static void *bpf_dl = NULL;
|
||||
|
||||
static DLSYM_PROTOTYPE(libbpf_get_error) = NULL;
|
||||
|
||||
DLSYM_PROTOTYPE(bpf_link__destroy) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_link__fd) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_link__open) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_link__pin) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__fd) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__name) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__set_inner_map_fd) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__set_max_entries) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__set_pin_path) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map_delete_elem) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map_get_fd_by_id) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map_lookup_elem) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map_update_elem) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_obj_get_info_by_fd) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__attach_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__destroy_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__detach_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__load_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__name) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__open_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__pin_maps) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__attach) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__attach_cgroup) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__attach_lsm) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__name) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__set_autoload) = NULL;
|
||||
DLSYM_PROTOTYPE(libbpf_set_print) = NULL;
|
||||
DLSYM_PROTOTYPE(ring_buffer__epoll_fd) = NULL;
|
||||
DLSYM_PROTOTYPE(ring_buffer__free) = NULL;
|
||||
DLSYM_PROTOTYPE(ring_buffer__new) = NULL;
|
||||
DLSYM_PROTOTYPE(ring_buffer__poll) = NULL;
|
||||
|
||||
/* new symbols available from libbpf 0.7.0 */
|
||||
int (*sym_bpf_map_create)(enum bpf_map_type, const char *, __u32, __u32, __u32, const struct bpf_map_create_opts *);
|
||||
struct bpf_map* (*sym_bpf_object__next_map)(const struct bpf_object *obj, const struct bpf_map *map);
|
||||
|
||||
/* compat symbols removed in libbpf 1.0 */
|
||||
int (*sym_bpf_create_map)(enum bpf_map_type, int key_size, int value_size, int max_entries, __u32 map_flags);
|
||||
|
||||
_printf_(2,0)
|
||||
static int bpf_print_func(enum libbpf_print_level level, const char *fmt, va_list ap) {
|
||||
#if !LOG_TRACE
|
||||
/* libbpf logs a lot of details at its debug level, which we don't need to see. */
|
||||
if (level == LIBBPF_DEBUG)
|
||||
return 0;
|
||||
#endif
|
||||
/* All other levels are downgraded to LOG_DEBUG */
|
||||
|
||||
/* errno is used here, on the assumption that if the log message uses %m, errno will be set to
|
||||
* something useful. Otherwise, it shouldn't matter, we may pass 0 or some bogus value. */
|
||||
return log_internalv(LOG_DEBUG, errno, NULL, 0, NULL, fmt, ap);
|
||||
}
|
||||
|
||||
int dlopen_bpf(int log_level) {
|
||||
static int cached = 0;
|
||||
int r;
|
||||
|
||||
if (cached != 0)
|
||||
return cached;
|
||||
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"bpf",
|
||||
"Support firewalling and sandboxing with BPF",
|
||||
SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
|
||||
"libbpf.so.1", "libbpf.so.0");
|
||||
|
||||
DISABLE_WARNING_DEPRECATED_DECLARATIONS;
|
||||
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
r = dlopen_safe("libbpf.so.1", &dl, /* reterr_dlerror= */ NULL);
|
||||
if (r < 0) {
|
||||
/* libbpf < 1.0.0 (we rely on 0.1.0+) provide most symbols we care about, but
|
||||
* unfortunately not all until 0.7.0. See bpf-compat.h for more details.
|
||||
* Once we consider we can assume 0.7+ is present we can just use the same symbol
|
||||
* list for both files, and when we assume 1.0+ is present we can remove this dlopen */
|
||||
const char *dle = NULL;
|
||||
r = dlopen_safe("libbpf.so.0", &dl, &dle);
|
||||
if (r < 0) {
|
||||
log_full_errno(in_initrd() ? LOG_DEBUG : log_level, r,
|
||||
"Neither libbpf.so.1 nor libbpf.so.0 are installed, cgroup BPF features disabled: %s", dle ?: STRERROR(r));
|
||||
return (cached = -EOPNOTSUPP); /* turn into recognizable error */
|
||||
}
|
||||
|
||||
log_debug("Loaded 'libbpf.so.0' via dlopen()");
|
||||
|
||||
/* symbols deprecated in 1.0 we use as compat */
|
||||
r = dlsym_many_or_warn(
|
||||
dl, LOG_DEBUG,
|
||||
#if MODERN_LIBBPF
|
||||
/* Don't exist anymore in new libbpf, hence cannot type check them */
|
||||
DLSYM_ARG_FORCE(bpf_create_map)
|
||||
#else
|
||||
DLSYM_ARG(bpf_create_map)
|
||||
#endif
|
||||
);
|
||||
|
||||
/* NB: we don't try to load bpf_object__next_map() on old versions */
|
||||
} else {
|
||||
log_debug("Loaded 'libbpf.so.1' via dlopen()");
|
||||
|
||||
/* symbols available from 0.7.0 */
|
||||
r = dlsym_many_or_warn(
|
||||
dl, LOG_DEBUG,
|
||||
#if MODERN_LIBBPF
|
||||
DLSYM_ARG(bpf_map_create),
|
||||
DLSYM_ARG(bpf_object__next_map)
|
||||
#else
|
||||
/* These symbols did not exist in old libbpf, hence we cannot type check them */
|
||||
DLSYM_ARG_FORCE(bpf_map_create),
|
||||
DLSYM_ARG_FORCE(bpf_object__next_map)
|
||||
#endif
|
||||
);
|
||||
}
|
||||
if (r < 0)
|
||||
return cached = log_full_errno(log_level, r, "Failed to load libbpf symbols, cgroup BPF features disabled: %m");
|
||||
|
||||
r = dlsym_many_or_warn(
|
||||
dl, LOG_DEBUG,
|
||||
DLSYM_ARG(bpf_link__destroy),
|
||||
DLSYM_ARG(bpf_link__fd),
|
||||
DLSYM_ARG(bpf_link__open),
|
||||
DLSYM_ARG(bpf_link__pin),
|
||||
DLSYM_ARG(bpf_map__fd),
|
||||
DLSYM_ARG(bpf_map__name),
|
||||
DLSYM_ARG(bpf_map__set_inner_map_fd),
|
||||
DLSYM_ARG(bpf_map__set_max_entries),
|
||||
DLSYM_ARG(bpf_map__set_pin_path),
|
||||
DLSYM_ARG(bpf_map_delete_elem),
|
||||
DLSYM_ARG(bpf_map_get_fd_by_id),
|
||||
DLSYM_ARG(bpf_map_lookup_elem),
|
||||
DLSYM_ARG(bpf_map_update_elem),
|
||||
DLSYM_ARG(bpf_obj_get_info_by_fd),
|
||||
DLSYM_ARG(bpf_object__attach_skeleton),
|
||||
DLSYM_ARG(bpf_object__destroy_skeleton),
|
||||
DLSYM_ARG(bpf_object__detach_skeleton),
|
||||
DLSYM_ARG(bpf_object__load_skeleton),
|
||||
DLSYM_ARG(bpf_object__name),
|
||||
DLSYM_ARG(bpf_object__open_skeleton),
|
||||
DLSYM_ARG(bpf_object__pin_maps),
|
||||
#if MODERN_LIBBPF
|
||||
DLSYM_ARG(bpf_program__attach),
|
||||
DLSYM_ARG(bpf_program__attach_cgroup),
|
||||
DLSYM_ARG(bpf_program__attach_lsm),
|
||||
#else
|
||||
/* libbpf added a "const" to function parameters where it should not have, ignore this type incompatibility */
|
||||
DLSYM_ARG_FORCE(bpf_program__attach),
|
||||
DLSYM_ARG_FORCE(bpf_program__attach_cgroup),
|
||||
DLSYM_ARG_FORCE(bpf_program__attach_lsm),
|
||||
#endif
|
||||
DLSYM_ARG(bpf_program__name),
|
||||
DLSYM_ARG(bpf_program__set_autoload),
|
||||
DLSYM_ARG(libbpf_get_error),
|
||||
DLSYM_ARG(libbpf_set_print),
|
||||
DLSYM_ARG(ring_buffer__epoll_fd),
|
||||
DLSYM_ARG(ring_buffer__free),
|
||||
DLSYM_ARG(ring_buffer__new),
|
||||
DLSYM_ARG(ring_buffer__poll));
|
||||
if (r < 0)
|
||||
return cached = log_full_errno(log_level, r, "Failed to load libbpf symbols, cgroup BPF features disabled: %m");
|
||||
|
||||
/* We set the print helper unconditionally. Otherwise libbpf will emit not useful log messages. */
|
||||
(void) sym_libbpf_set_print(bpf_print_func);
|
||||
|
||||
REENABLE_WARNING;
|
||||
|
||||
bpf_dl = TAKE_PTR(dl);
|
||||
|
||||
return cached = true;
|
||||
}
|
||||
|
||||
int bpf_get_error_translated(const void *ptr) {
|
||||
int r;
|
||||
|
||||
r = sym_libbpf_get_error(ptr);
|
||||
|
||||
switch (r) {
|
||||
case -524:
|
||||
/* Workaround for kernel bug, BPF returns an internal error instead of translating it, until
|
||||
* it is fixed:
|
||||
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/errno.h?h=v6.9&id=a38297e3fb012ddfa7ce0321a7e5a8daeb1872b6#n27
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
default:
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int dlopen_bpf(int log_level) {
|
||||
return log_once_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"libbpf support is not compiled in, cgroup BPF features disabled.");
|
||||
}
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "bpf-link.h"
|
||||
#include "serialize.h"
|
||||
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "sd-dlopen.h"
|
||||
|
||||
#include "bpf-util.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "log.h"
|
||||
#include "strv.h"
|
||||
|
||||
#if HAVE_LIBBPF
|
||||
|
||||
/* libbpf changed types of function prototypes around, so we need to disable some type checking for older
|
||||
* libbpf. We consider everything older than 0.7 too old for accurate type checks. */
|
||||
#if defined(__LIBBPF_CURRENT_VERSION_GEQ)
|
||||
#if __LIBBPF_CURRENT_VERSION_GEQ(0, 7)
|
||||
#define MODERN_LIBBPF 1
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(MODERN_LIBBPF)
|
||||
#define MODERN_LIBBPF 0
|
||||
#endif
|
||||
|
||||
static DLSYM_PROTOTYPE(libbpf_get_error) = NULL;
|
||||
|
||||
DLSYM_PROTOTYPE(bpf_create_map) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_link__destroy) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_link__fd) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_link__open) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_link__pin) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__fd) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__name) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__set_inner_map_fd) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__set_max_entries) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map__set_pin_path) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map_create) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map_delete_elem) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map_get_fd_by_id) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map_lookup_elem) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_map_update_elem) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_obj_get_info_by_fd) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__attach_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__destroy_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__detach_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__load_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__name) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__next_map) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__open_skeleton) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_object__pin_maps) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__attach) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__attach_cgroup) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__attach_lsm) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__name) = NULL;
|
||||
DLSYM_PROTOTYPE(bpf_program__set_autoload) = NULL;
|
||||
static int missing_bpf_token_create(int bpffs_fd, struct bpf_token_create_opts *opts) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
DLSYM_PROTOTYPE(bpf_token_create) = missing_bpf_token_create;
|
||||
DLSYM_PROTOTYPE(libbpf_set_print) = NULL;
|
||||
DLSYM_PROTOTYPE(ring_buffer__epoll_fd) = NULL;
|
||||
DLSYM_PROTOTYPE(ring_buffer__free) = NULL;
|
||||
DLSYM_PROTOTYPE(ring_buffer__new) = NULL;
|
||||
DLSYM_PROTOTYPE(ring_buffer__poll) = NULL;
|
||||
|
||||
_printf_(2,0)
|
||||
static int bpf_print_func(enum libbpf_print_level level, const char *fmt, va_list ap) {
|
||||
#if !LOG_TRACE
|
||||
/* libbpf logs a lot of details at its debug level, which we don't need to see. */
|
||||
if (level == LIBBPF_DEBUG)
|
||||
return 0;
|
||||
#endif
|
||||
/* All other levels are downgraded to LOG_DEBUG */
|
||||
|
||||
/* errno is used here, on the assumption that if the log message uses %m, errno will be set to
|
||||
* something useful. Otherwise, it shouldn't matter, we may pass 0 or some bogus value. */
|
||||
return log_internalv(LOG_DEBUG, errno, NULL, 0, NULL, fmt, ap);
|
||||
}
|
||||
|
||||
int dlopen_bpf(int log_level) {
|
||||
static void *bpf_dl = NULL;
|
||||
int r;
|
||||
|
||||
SD_ELF_NOTE_DLOPEN(
|
||||
"bpf",
|
||||
"Support firewalling and sandboxing with BPF",
|
||||
SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
|
||||
"libbpf.so.1", "libbpf.so.0");
|
||||
|
||||
DISABLE_WARNING_DEPRECATED_DECLARATIONS;
|
||||
|
||||
FOREACH_STRING(soname, "libbpf.so.1", "libbpf.so.0") {
|
||||
r = dlopen_many_sym_or_warn(
|
||||
&bpf_dl, soname, LOG_DEBUG,
|
||||
DLSYM_ARG(bpf_link__destroy),
|
||||
DLSYM_ARG(bpf_link__fd),
|
||||
DLSYM_ARG(bpf_link__open),
|
||||
DLSYM_ARG(bpf_link__pin),
|
||||
DLSYM_ARG(bpf_map__fd),
|
||||
DLSYM_ARG(bpf_map__name),
|
||||
DLSYM_ARG(bpf_map__set_inner_map_fd),
|
||||
DLSYM_ARG(bpf_map__set_max_entries),
|
||||
DLSYM_ARG(bpf_map__set_pin_path),
|
||||
DLSYM_ARG(bpf_map_delete_elem),
|
||||
DLSYM_ARG(bpf_map_get_fd_by_id),
|
||||
DLSYM_ARG(bpf_map_lookup_elem),
|
||||
DLSYM_ARG(bpf_map_update_elem),
|
||||
DLSYM_ARG(bpf_obj_get_info_by_fd),
|
||||
DLSYM_ARG(bpf_object__attach_skeleton),
|
||||
DLSYM_ARG(bpf_object__destroy_skeleton),
|
||||
DLSYM_ARG(bpf_object__detach_skeleton),
|
||||
DLSYM_ARG(bpf_object__load_skeleton),
|
||||
DLSYM_ARG(bpf_object__name),
|
||||
DLSYM_ARG(bpf_object__open_skeleton),
|
||||
DLSYM_ARG(bpf_object__pin_maps),
|
||||
#if MODERN_LIBBPF
|
||||
DLSYM_ARG(bpf_program__attach),
|
||||
DLSYM_ARG(bpf_program__attach_cgroup),
|
||||
DLSYM_ARG(bpf_program__attach_lsm),
|
||||
#else
|
||||
/* libbpf added a "const" to function parameters where it should not have, ignore this type incompatibility */
|
||||
DLSYM_ARG_FORCE(bpf_program__attach),
|
||||
DLSYM_ARG_FORCE(bpf_program__attach_cgroup),
|
||||
DLSYM_ARG_FORCE(bpf_program__attach_lsm),
|
||||
#endif
|
||||
DLSYM_ARG(bpf_program__name),
|
||||
DLSYM_ARG(bpf_program__set_autoload),
|
||||
DLSYM_ARG(libbpf_get_error),
|
||||
DLSYM_ARG(libbpf_set_print),
|
||||
DLSYM_ARG(ring_buffer__epoll_fd),
|
||||
DLSYM_ARG(ring_buffer__free),
|
||||
DLSYM_ARG(ring_buffer__new),
|
||||
DLSYM_ARG(ring_buffer__poll));
|
||||
if (r >= 0)
|
||||
break;
|
||||
}
|
||||
REENABLE_WARNING;
|
||||
if (r < 0)
|
||||
return log_full_errno(in_initrd() ? LOG_DEBUG : log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Neither libbpf.so.1 nor libbpf.so.0 are installed, cgroup BPF features disabled.");
|
||||
|
||||
/* Version-specific symbols: bpf_create_map exists only in libbpf < 1.0; bpf_map_create and
|
||||
* bpf_object__next_map only in 0.7+. bpf_token_create only in 1.5+. Unresolved prototypes keep
|
||||
* their initializers (NULL, or a fallback returning -ENOSYS for bpf_token_create). */
|
||||
DLSYM_OPTIONAL(bpf_dl, bpf_create_map);
|
||||
DLSYM_OPTIONAL(bpf_dl, bpf_map_create);
|
||||
DLSYM_OPTIONAL(bpf_dl, bpf_object__next_map);
|
||||
DLSYM_OPTIONAL(bpf_dl, bpf_token_create);
|
||||
|
||||
/* We set the print helper unconditionally. Otherwise libbpf will emit not useful log messages. */
|
||||
(void) sym_libbpf_set_print(bpf_print_func);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bpf_get_error_translated(const void *ptr) {
|
||||
int r;
|
||||
|
||||
r = sym_libbpf_get_error(ptr);
|
||||
|
||||
switch (r) {
|
||||
case -524:
|
||||
/* Workaround for kernel bug, BPF returns an internal error instead of translating it, until
|
||||
* it is fixed:
|
||||
* https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/errno.h?h=v6.9&id=a38297e3fb012ddfa7ce0321a7e5a8daeb1872b6#n27
|
||||
*/
|
||||
return -EOPNOTSUPP;
|
||||
default:
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int dlopen_bpf(int log_level) {
|
||||
return log_once_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"libbpf support is not compiled in, cgroup BPF features disabled.");
|
||||
}
|
||||
#endif
|
||||
@@ -8,10 +8,27 @@
|
||||
#include <bpf/bpf.h> /* IWYU pragma: export */
|
||||
#include <bpf/libbpf.h> /* IWYU pragma: export */
|
||||
|
||||
#include "bpf-compat.h" /* IWYU pragma: export */
|
||||
#include "dlfcn-util.h"
|
||||
#include "shared-forward.h"
|
||||
|
||||
/* Always redeclare these so DLSYM_PROTOTYPE's typeof() resolves regardless of libbpf version;
|
||||
* suppress the warning when the libbpf headers already declare them.
|
||||
* - bpf_map_create, bpf_object__next_map: available since libbpf 0.7
|
||||
* - bpf_token_create: available since libbpf 1.5
|
||||
* - bpf_create_map: removed in libbpf 1.0
|
||||
*/
|
||||
DISABLE_WARNING_REDUNDANT_DECLS;
|
||||
/* NOLINTBEGIN(readability-redundant-declaration) */
|
||||
struct bpf_map_create_opts;
|
||||
struct bpf_token_create_opts;
|
||||
extern int bpf_create_map(enum bpf_map_type, int key_size, int value_size, int max_entries, __u32 map_flags);
|
||||
extern int bpf_map_create(enum bpf_map_type, const char *, __u32, __u32, __u32, const struct bpf_map_create_opts *);
|
||||
extern struct bpf_map* bpf_object__next_map(const struct bpf_object *obj, const struct bpf_map *map);
|
||||
extern int bpf_token_create(int bpffs_fd, struct bpf_token_create_opts *opts);
|
||||
/* NOLINTEND(readability-redundant-declaration) */
|
||||
REENABLE_WARNING;
|
||||
|
||||
extern DLSYM_PROTOTYPE(bpf_create_map);
|
||||
extern DLSYM_PROTOTYPE(bpf_link__destroy);
|
||||
extern DLSYM_PROTOTYPE(bpf_link__fd);
|
||||
extern DLSYM_PROTOTYPE(bpf_link__open);
|
||||
@@ -21,6 +38,7 @@ extern DLSYM_PROTOTYPE(bpf_map__name);
|
||||
extern DLSYM_PROTOTYPE(bpf_map__set_inner_map_fd);
|
||||
extern DLSYM_PROTOTYPE(bpf_map__set_max_entries);
|
||||
extern DLSYM_PROTOTYPE(bpf_map__set_pin_path);
|
||||
extern DLSYM_PROTOTYPE(bpf_map_create);
|
||||
extern DLSYM_PROTOTYPE(bpf_map_delete_elem);
|
||||
extern DLSYM_PROTOTYPE(bpf_map_get_fd_by_id);
|
||||
extern DLSYM_PROTOTYPE(bpf_map_lookup_elem);
|
||||
@@ -33,6 +51,7 @@ extern DLSYM_PROTOTYPE(bpf_object__destroy_skeleton);
|
||||
extern DLSYM_PROTOTYPE(bpf_object__detach_skeleton);
|
||||
extern DLSYM_PROTOTYPE(bpf_object__load_skeleton);
|
||||
extern DLSYM_PROTOTYPE(bpf_object__name);
|
||||
extern DLSYM_PROTOTYPE(bpf_object__next_map);
|
||||
extern DLSYM_PROTOTYPE(bpf_object__open_skeleton);
|
||||
extern DLSYM_PROTOTYPE(bpf_object__pin_maps);
|
||||
extern DLSYM_PROTOTYPE(bpf_program__attach);
|
||||
@@ -40,12 +59,30 @@ extern DLSYM_PROTOTYPE(bpf_program__attach_cgroup);
|
||||
extern DLSYM_PROTOTYPE(bpf_program__attach_lsm);
|
||||
extern DLSYM_PROTOTYPE(bpf_program__name);
|
||||
extern DLSYM_PROTOTYPE(bpf_program__set_autoload);
|
||||
extern DLSYM_PROTOTYPE(bpf_token_create);
|
||||
extern DLSYM_PROTOTYPE(libbpf_set_print);
|
||||
extern DLSYM_PROTOTYPE(ring_buffer__epoll_fd);
|
||||
extern DLSYM_PROTOTYPE(ring_buffer__free);
|
||||
extern DLSYM_PROTOTYPE(ring_buffer__new);
|
||||
extern DLSYM_PROTOTYPE(ring_buffer__poll);
|
||||
|
||||
/* Helper that uses the available variant behind the new API. */
|
||||
static inline int compat_bpf_map_create(
|
||||
enum bpf_map_type map_type,
|
||||
const char *map_name,
|
||||
__u32 key_size,
|
||||
__u32 value_size,
|
||||
__u32 max_entries,
|
||||
const struct bpf_map_create_opts *opts) {
|
||||
|
||||
if (sym_bpf_map_create)
|
||||
return sym_bpf_map_create(map_type, map_name, key_size,
|
||||
value_size, max_entries, opts);
|
||||
|
||||
return sym_bpf_create_map(map_type, key_size, value_size, max_entries,
|
||||
0 /* opts->map_flags, but opts is always NULL for us so skip build dependency on the type */);
|
||||
}
|
||||
|
||||
/* libbpf sometimes returns error codes that make sense only in the kernel, like 524 for EOPNOTSUPP. Use
|
||||
* this helper instead of libbpf_get_error() to ensure some of the known ones are translated into errnos
|
||||
* we understand. */
|
||||
+25
-19
@@ -11,8 +11,8 @@ void rgb_to_hsv(double r, double g, double b,
|
||||
assert(g >= 0 && g <= 1);
|
||||
assert(b >= 0 && b <= 1);
|
||||
|
||||
double max_color = fmax(r, fmax(g, b));
|
||||
double min_color = fmin(r, fmin(g, b));
|
||||
double max_color = MAX(r, MAX(g, b));
|
||||
double min_color = MIN(r, MIN(g, b));
|
||||
double delta = max_color - min_color;
|
||||
|
||||
if (ret_v)
|
||||
@@ -32,13 +32,15 @@ void rgb_to_hsv(double r, double g, double b,
|
||||
if (ret_h) {
|
||||
if (delta > 0) {
|
||||
if (r >= max_color)
|
||||
*ret_h = 60 * fmod((g - b) / delta, 6);
|
||||
*ret_h = 60 * (g - b) / delta;
|
||||
else if (g >= max_color)
|
||||
*ret_h = 60 * (((b - r) / delta) + 2);
|
||||
else if (b >= max_color)
|
||||
else /* b >= max_color */
|
||||
*ret_h = 60 * (((r - g) / delta) + 4);
|
||||
|
||||
*ret_h = fmod(*ret_h, 360);
|
||||
/* The r-max branch produces (-60, 60); fold the negative half up. */
|
||||
if (*ret_h < 0)
|
||||
*ret_h += 360;
|
||||
} else
|
||||
*ret_h = NAN;
|
||||
}
|
||||
@@ -49,29 +51,33 @@ void hsv_to_rgb(double h, double s, double v,
|
||||
|
||||
double c, x, m, r, g, b;
|
||||
|
||||
assert(h >= 0 && h <= 360);
|
||||
assert(s >= 0 && s <= 100);
|
||||
assert(v >= 0 && v <= 100);
|
||||
assert(ret_r);
|
||||
assert(ret_g);
|
||||
assert(ret_b);
|
||||
|
||||
h = fmod(h, 360);
|
||||
c = (s / 100.0) * (v / 100.0);
|
||||
x = c * (1 - fabs(fmod(h / 60.0, 2) - 1));
|
||||
m = (v / 100) - c;
|
||||
|
||||
if (h >= 0 && h < 60)
|
||||
r = c, g = x, b = 0.0;
|
||||
else if (h >= 60 && h < 120)
|
||||
r = x, g = c, b = 0.0;
|
||||
else if (h >= 120 && h < 180)
|
||||
r = 0.0, g = c, b = x;
|
||||
else if (h >= 180 && h < 240)
|
||||
r = 0.0, g = x, b = c;
|
||||
else if (h >= 240 && h < 300)
|
||||
r = x, g = 0.0, b = c;
|
||||
else
|
||||
r = c, g = 0.0, b = x;
|
||||
/* Split h into sector index k ∈ [0, 6] and fractional offset f ∈ [0, 1) within the sector.
|
||||
* Within each sector exactly one of {r, g, b} equals c, one equals 0, and the third (x)
|
||||
* ramps linearly between them — ascending in even sectors, descending in odd. h == 360 is
|
||||
* the cyclic boundary equivalent to h == 0, and maps to sector 0. */
|
||||
double seg = h / 60.0;
|
||||
int k = (int) seg % 6;
|
||||
double f = seg - (int) seg;
|
||||
x = c * (k & 1 ? 1.0 - f : f);
|
||||
|
||||
switch (k) {
|
||||
case 0: r = c; g = x; b = 0.0; break;
|
||||
case 1: r = x; g = c; b = 0.0; break;
|
||||
case 2: r = 0.0; g = c; b = x; break;
|
||||
case 3: r = 0.0; g = x; b = c; break;
|
||||
case 4: r = x; g = 0.0; b = c; break;
|
||||
default: r = c; g = 0.0; b = x; break;
|
||||
}
|
||||
|
||||
*ret_r = (uint8_t) ((r + m) * 255);
|
||||
*ret_g = (uint8_t) ((g + m) * 255);
|
||||
|
||||
@@ -45,6 +45,7 @@ DLSYM_PROTOTYPE(crypt_keyslot_destroy) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_keyslot_max) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_keyslot_status) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_load) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_logf) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_metadata_locking) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_persistent_flags_get) = NULL;
|
||||
DLSYM_PROTOTYPE(crypt_persistent_flags_set) = NULL;
|
||||
@@ -315,6 +316,7 @@ int dlopen_cryptsetup(int log_level) {
|
||||
DLSYM_ARG(crypt_keyslot_max),
|
||||
DLSYM_ARG(crypt_keyslot_status),
|
||||
DLSYM_ARG(crypt_load),
|
||||
DLSYM_ARG(crypt_logf),
|
||||
DLSYM_ARG(crypt_metadata_locking),
|
||||
DLSYM_ARG(crypt_persistent_flags_get),
|
||||
DLSYM_ARG(crypt_persistent_flags_set),
|
||||
|
||||
@@ -46,6 +46,7 @@ extern DLSYM_PROTOTYPE(crypt_keyslot_destroy);
|
||||
extern DLSYM_PROTOTYPE(crypt_keyslot_max);
|
||||
extern DLSYM_PROTOTYPE(crypt_keyslot_status);
|
||||
extern DLSYM_PROTOTYPE(crypt_load);
|
||||
extern DLSYM_PROTOTYPE(crypt_logf);
|
||||
extern DLSYM_PROTOTYPE(crypt_metadata_locking);
|
||||
extern DLSYM_PROTOTYPE(crypt_persistent_flags_get);
|
||||
extern DLSYM_PROTOTYPE(crypt_persistent_flags_set);
|
||||
|
||||
@@ -19,8 +19,8 @@ shared_sources = files(
|
||||
'boot-entry.c',
|
||||
'boot-timestamps.c',
|
||||
'bootspec.c',
|
||||
'bpf-dlopen.c',
|
||||
'bpf-program.c',
|
||||
'bpf-util.c',
|
||||
'bridge-util.c',
|
||||
'btrfs-util.c',
|
||||
'bus-get-properties.c',
|
||||
@@ -383,8 +383,7 @@ shared_sources += [dns_type_from_name_inc, dns_type_to_name_inc]
|
||||
|
||||
libshared_name = 'systemd-shared-@0@'.format(shared_lib_tag)
|
||||
|
||||
libshared_deps = [threads,
|
||||
libacl_cflags,
|
||||
libshared_deps = [libacl_cflags,
|
||||
libapparmor_cflags,
|
||||
libarchive_cflags,
|
||||
libaudit_cflags,
|
||||
@@ -393,7 +392,6 @@ libshared_deps = [threads,
|
||||
libcrypt_cflags,
|
||||
libcryptsetup_cflags,
|
||||
libcurl_cflags,
|
||||
libdl,
|
||||
libdw_cflags,
|
||||
libelf_cflags,
|
||||
libfdisk_cflags,
|
||||
@@ -410,7 +408,6 @@ libshared_deps = [threads,
|
||||
libpcre2_cflags,
|
||||
libpwquality_cflags,
|
||||
libqrencode_cflags,
|
||||
librt,
|
||||
libseccomp_cflags,
|
||||
libselinux_cflags,
|
||||
libxenctrl_cflags,
|
||||
|
||||
@@ -25,10 +25,15 @@ static void *libpam_dl = NULL;
|
||||
DLSYM_PROTOTYPE(pam_acct_mgmt) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_close_session) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_end) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_authtok_noverify) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_authtok_verify) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_data) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_item) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_get_user) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_getenv) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_getenvlist) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_open_session) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_prompt) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_putenv) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_set_data) = NULL;
|
||||
DLSYM_PROTOTYPE(pam_set_item) = NULL;
|
||||
@@ -361,6 +366,19 @@ int pam_prompt_graceful(pam_handle_t *pamh, int style, char **ret_response, cons
|
||||
return PAM_SUCCESS;
|
||||
}
|
||||
|
||||
int pam_putenv_assign(pam_handle_t *pamh, const char *name, const char *value) {
|
||||
_cleanup_(erase_and_freep) char *s = NULL;
|
||||
|
||||
assert(pamh);
|
||||
assert(name);
|
||||
assert(value);
|
||||
|
||||
if (asprintf(&s, "%s=%s", name, value) < 0)
|
||||
return PAM_BUF_ERR;
|
||||
|
||||
return sym_pam_putenv(pamh, s);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int dlopen_libpam(int log_level) {
|
||||
@@ -378,10 +396,15 @@ int dlopen_libpam(int log_level) {
|
||||
DLSYM_ARG(pam_acct_mgmt),
|
||||
DLSYM_ARG(pam_close_session),
|
||||
DLSYM_ARG(pam_end),
|
||||
DLSYM_ARG(pam_get_authtok_noverify),
|
||||
DLSYM_ARG(pam_get_authtok_verify),
|
||||
DLSYM_ARG(pam_get_data),
|
||||
DLSYM_ARG(pam_get_item),
|
||||
DLSYM_ARG(pam_get_user),
|
||||
DLSYM_ARG(pam_getenv),
|
||||
DLSYM_ARG(pam_getenvlist),
|
||||
DLSYM_ARG(pam_open_session),
|
||||
DLSYM_ARG(pam_prompt),
|
||||
DLSYM_ARG(pam_putenv),
|
||||
DLSYM_ARG(pam_set_data),
|
||||
DLSYM_ARG(pam_set_item),
|
||||
|
||||
+15
-1
@@ -6,7 +6,7 @@
|
||||
#if HAVE_PAM
|
||||
#include <security/pam_appl.h>
|
||||
#include <security/pam_ext.h>
|
||||
#include <security/pam_modules.h> /* IWYU pragma: export */
|
||||
#include <security/pam_modules.h> /* IWYU pragma: export */
|
||||
#include <syslog.h>
|
||||
|
||||
#include "dlfcn-util.h"
|
||||
@@ -14,10 +14,15 @@
|
||||
extern DLSYM_PROTOTYPE(pam_acct_mgmt);
|
||||
extern DLSYM_PROTOTYPE(pam_close_session);
|
||||
extern DLSYM_PROTOTYPE(pam_end);
|
||||
extern DLSYM_PROTOTYPE(pam_get_authtok_noverify);
|
||||
extern DLSYM_PROTOTYPE(pam_get_authtok_verify);
|
||||
extern DLSYM_PROTOTYPE(pam_get_data);
|
||||
extern DLSYM_PROTOTYPE(pam_get_item);
|
||||
extern DLSYM_PROTOTYPE(pam_get_user);
|
||||
extern DLSYM_PROTOTYPE(pam_getenv);
|
||||
extern DLSYM_PROTOTYPE(pam_getenvlist);
|
||||
extern DLSYM_PROTOTYPE(pam_open_session);
|
||||
extern DLSYM_PROTOTYPE(pam_prompt);
|
||||
extern DLSYM_PROTOTYPE(pam_putenv);
|
||||
extern DLSYM_PROTOTYPE(pam_set_data);
|
||||
extern DLSYM_PROTOTYPE(pam_set_item);
|
||||
@@ -27,6 +32,11 @@ extern DLSYM_PROTOTYPE(pam_strerror);
|
||||
extern DLSYM_PROTOTYPE(pam_syslog);
|
||||
extern DLSYM_PROTOTYPE(pam_vsyslog);
|
||||
|
||||
/* sym_pam_prompt() replacement for the pam_info() macro from <security/pam_ext.h>, which expands to a direct
|
||||
* pam_prompt() call. */
|
||||
#define sym_pam_info(pamh, fmt, ...) \
|
||||
sym_pam_prompt((pamh), PAM_TEXT_INFO, NULL, (fmt), ## __VA_ARGS__)
|
||||
|
||||
void pam_log_setup(void);
|
||||
|
||||
int errno_to_pam_error(int error) _const_;
|
||||
@@ -90,6 +100,10 @@ int pam_get_data_many_internal(pam_handle_t *pamh, ...) _sentinel_;
|
||||
|
||||
int pam_prompt_graceful(pam_handle_t *pamh, int style, char **ret_response, const char *fmt, ...) _printf_(4,5);
|
||||
|
||||
/* Equivalent of pam_misc_setenv(pamh, name, value, 0), without the libpam_misc dep — builds "name=value"
|
||||
* and hands it to sym_pam_putenv(), then erases the buffer before freeing in case it carried a secret. */
|
||||
int pam_putenv_assign(pam_handle_t *pamh, const char *name, const char *value);
|
||||
|
||||
#endif
|
||||
|
||||
int dlopen_libpam(int log_level);
|
||||
|
||||
@@ -5,6 +5,5 @@ executables += [
|
||||
'name' : 'systemd-socket-activate',
|
||||
'public' : true,
|
||||
'sources' : files('socket-activate.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -5,6 +5,5 @@ executables += [
|
||||
'name' : 'systemd-socket-proxyd',
|
||||
'public' : true,
|
||||
'sources' : files('socket-proxyd.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -58,7 +58,6 @@ executables += [
|
||||
liblz4_cflags,
|
||||
libxz_cflags,
|
||||
libzstd_cflags,
|
||||
threads,
|
||||
],
|
||||
'install_tag' : 'systemctl',
|
||||
},
|
||||
|
||||
@@ -30,7 +30,6 @@ executables += [
|
||||
'dependencies' : [
|
||||
libfdisk_cflags,
|
||||
libopenssl_cflags,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
libexec_template + {
|
||||
@@ -38,7 +37,6 @@ executables += [
|
||||
'dbus' : true,
|
||||
'conditions' : ['ENABLE_SYSUPDATED'],
|
||||
'sources' : files('sysupdated.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
executable_template + {
|
||||
'name' : 'updatectl',
|
||||
|
||||
+6
-27
@@ -223,10 +223,8 @@ simple_tests += files(
|
||||
|
||||
common_test_dependencies = [
|
||||
libmount_cflags,
|
||||
librt,
|
||||
libseccomp_cflags,
|
||||
libselinux_cflags,
|
||||
threads,
|
||||
]
|
||||
|
||||
executables += [
|
||||
@@ -303,14 +301,13 @@ executables += [
|
||||
],
|
||||
},
|
||||
test_template + {
|
||||
# only static linking apart from libdl, to make sure that the
|
||||
# module is linked to all libraries that it uses.
|
||||
# only static linking, to make sure that the module is linked
|
||||
# to all libraries that it uses.
|
||||
'sources' : files('test-dlopen.c'),
|
||||
'link_with' : [
|
||||
libc_wrapper_static,
|
||||
libbasic_static,
|
||||
],
|
||||
'dependencies' : libdl,
|
||||
'install' : false,
|
||||
'type' : 'manual',
|
||||
},
|
||||
@@ -359,10 +356,7 @@ executables += [
|
||||
test_template + {
|
||||
'sources' : files('test-libmount.c'),
|
||||
'conditions' : ['HAVE_LIBMOUNT'],
|
||||
'dependencies' : [
|
||||
libmount_cflags,
|
||||
threads,
|
||||
],
|
||||
'dependencies' : libmount_cflags,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-loopback.c'),
|
||||
@@ -378,7 +372,6 @@ executables += [
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-pressure.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-mount-util.c'),
|
||||
@@ -398,17 +391,13 @@ executables += [
|
||||
test_template + {
|
||||
'sources' : files('test-nss-hosts.c'),
|
||||
'extract' : files('nss-test-util.c'),
|
||||
'dependencies' : [
|
||||
libdl,
|
||||
libseccomp_cflags,
|
||||
],
|
||||
'dependencies' : libseccomp_cflags,
|
||||
'conditions' : ['ENABLE_NSS'],
|
||||
'timeout' : 120,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-nss-users.c'),
|
||||
'objects' : ['test-nss-hosts'],
|
||||
'dependencies' : libdl,
|
||||
'conditions' : ['ENABLE_NSS'],
|
||||
},
|
||||
test_template + {
|
||||
@@ -426,7 +415,6 @@ executables += [
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-process-util.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-progress-bar.c'),
|
||||
@@ -441,7 +429,6 @@ executables += [
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-qrcode-util.c'),
|
||||
'dependencies' : libdl,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-random-util.c'),
|
||||
@@ -471,7 +458,6 @@ executables += [
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-set-disable-mempool.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-sizeof.c'),
|
||||
@@ -554,7 +540,7 @@ executables += [
|
||||
},
|
||||
core_test_template + {
|
||||
'sources' : files('test-bpf-token.c'),
|
||||
'dependencies' : common_test_dependencies + libbpf,
|
||||
'dependencies' : common_test_dependencies + libbpf_cflags,
|
||||
'conditions' : ['BPF_FRAMEWORK'],
|
||||
'type' : 'manual',
|
||||
},
|
||||
@@ -603,7 +589,6 @@ executables += [
|
||||
},
|
||||
core_test_template + {
|
||||
'sources' : files('test-loop-util.c'),
|
||||
'dependencies' : [threads],
|
||||
'parallel' : false,
|
||||
},
|
||||
core_test_template + {
|
||||
@@ -611,10 +596,7 @@ executables += [
|
||||
},
|
||||
core_test_template + {
|
||||
'sources' : files('test-namespace.c'),
|
||||
'dependencies' : [
|
||||
threads,
|
||||
libmount_cflags,
|
||||
],
|
||||
'dependencies' : libmount_cflags,
|
||||
},
|
||||
core_test_template + {
|
||||
'sources' : files('test-ns.c'),
|
||||
@@ -632,7 +614,6 @@ executables += [
|
||||
},
|
||||
core_test_template + {
|
||||
'sources' : files('test-socket-bind.c'),
|
||||
'dependencies' : libdl,
|
||||
'conditions' : ['BPF_FRAMEWORK'],
|
||||
},
|
||||
core_test_template + {
|
||||
@@ -666,7 +647,6 @@ executables += [
|
||||
libbasic_static,
|
||||
libsystemd,
|
||||
],
|
||||
'dependencies' : threads,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('../libudev/test-udev-device-thread.c'),
|
||||
@@ -675,7 +655,6 @@ executables += [
|
||||
libbasic_static,
|
||||
libudev,
|
||||
],
|
||||
'dependencies' : threads,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('../libudev/test-libudev.c'),
|
||||
|
||||
@@ -92,7 +92,7 @@ static int do_mprotect_exec(const char *path) {
|
||||
}
|
||||
|
||||
#if BPF_FRAMEWORK && HAVE_LSM_INTEGRITY_TYPE
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "restrict-fsaccess-skel.h"
|
||||
|
||||
static struct restrict_fsaccess_bpf *restrict_fsaccess_bpf_free(struct restrict_fsaccess_bpf *obj) {
|
||||
|
||||
@@ -1,26 +1,34 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <bpf/bpf.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "bpf-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "main-func.h"
|
||||
#include "tests.h" /* NOLINT(misc-include-cleaner): this is needed conditionally */
|
||||
#include "tests.h"
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
#if defined(LIBBPF_MAJOR_VERSION) && (LIBBPF_MAJOR_VERSION > 1 || (LIBBPF_MAJOR_VERSION == 1 && LIBBPF_MINOR_VERSION >= 5))
|
||||
_cleanup_close_ int bpffs_fd = open("/sys/fs/bpf", O_RDONLY);
|
||||
#if HAVE_LIBBPF
|
||||
int r;
|
||||
|
||||
r = dlopen_bpf(LOG_ERR);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_close_ int bpffs_fd = open("/sys/fs/bpf", O_CLOEXEC|O_RDONLY);
|
||||
if (bpffs_fd < 0)
|
||||
return log_error_errno(errno, "Failed to open '/sys/fs/bpf': %m");
|
||||
|
||||
_cleanup_close_ int token_fd = bpf_token_create(bpffs_fd, /* opts= */ NULL);
|
||||
_cleanup_close_ int token_fd = sym_bpf_token_create(bpffs_fd, /* opts= */ NULL);
|
||||
if (token_fd == -ENOSYS)
|
||||
return log_tests_skipped("bpf_token_create() unavailable (libbpf too old or kernel lacks BPF_TOKEN_CREATE support)");
|
||||
if (token_fd < 0)
|
||||
return log_error_errno(errno, "Failed to create bpf token: %m");
|
||||
return log_error_errno(token_fd, "Failed to create bpf token: %m");
|
||||
|
||||
log_info("Successfully created token fd.");
|
||||
return 0;
|
||||
#else
|
||||
return log_tests_skipped("libbpf is older than v1.5");
|
||||
return log_tests_skipped("BPF framework support is disabled");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+97
-29
@@ -6,58 +6,126 @@
|
||||
TEST(hsv_to_rgb) {
|
||||
uint8_t r, g, b;
|
||||
|
||||
/* Black at any hue. */
|
||||
hsv_to_rgb(0, 0, 0, &r, &g, &b);
|
||||
assert(r == 0 && g == 0 && b == 0);
|
||||
ASSERT_EQ(r, 0);
|
||||
ASSERT_EQ(g, 0);
|
||||
ASSERT_EQ(b, 0);
|
||||
|
||||
hsv_to_rgb(60, 0, 0, &r, &g, &b);
|
||||
assert(r == 0 && g == 0 && b == 0);
|
||||
ASSERT_EQ(r, 0);
|
||||
ASSERT_EQ(g, 0);
|
||||
ASSERT_EQ(b, 0);
|
||||
|
||||
/* White: s=0 must ignore hue. */
|
||||
hsv_to_rgb(0, 0, 100, &r, &g, &b);
|
||||
assert(r == 255 && g == 255 && b == 255);
|
||||
ASSERT_EQ(r, 255);
|
||||
ASSERT_EQ(g, 255);
|
||||
ASSERT_EQ(b, 255);
|
||||
|
||||
hsv_to_rgb(0, 100, 100, &r, &g, &b);
|
||||
assert(r == 255 && g == 0 && b == 0);
|
||||
hsv_to_rgb(180, 0, 100, &r, &g, &b);
|
||||
ASSERT_EQ(r, 255);
|
||||
ASSERT_EQ(g, 255);
|
||||
ASSERT_EQ(b, 255);
|
||||
|
||||
hsv_to_rgb(120, 100, 100, &r, &g, &b);
|
||||
assert(r == 0 && g == 255 && b == 0);
|
||||
/* Pure primary and secondary colors — one per sector boundary. */
|
||||
hsv_to_rgb(0, 100, 100, &r, &g, &b); /* red */
|
||||
ASSERT_EQ(r, 255); ASSERT_EQ(g, 0); ASSERT_EQ(b, 0);
|
||||
hsv_to_rgb(60, 100, 100, &r, &g, &b); /* yellow */
|
||||
ASSERT_EQ(r, 255); ASSERT_EQ(g, 255); ASSERT_EQ(b, 0);
|
||||
hsv_to_rgb(120, 100, 100, &r, &g, &b); /* green */
|
||||
ASSERT_EQ(r, 0); ASSERT_EQ(g, 255); ASSERT_EQ(b, 0);
|
||||
hsv_to_rgb(180, 100, 100, &r, &g, &b); /* cyan */
|
||||
ASSERT_EQ(r, 0); ASSERT_EQ(g, 255); ASSERT_EQ(b, 255);
|
||||
hsv_to_rgb(240, 100, 100, &r, &g, &b); /* blue */
|
||||
ASSERT_EQ(r, 0); ASSERT_EQ(g, 0); ASSERT_EQ(b, 255);
|
||||
hsv_to_rgb(300, 100, 100, &r, &g, &b); /* magenta */
|
||||
ASSERT_EQ(r, 255); ASSERT_EQ(g, 0); ASSERT_EQ(b, 255);
|
||||
|
||||
hsv_to_rgb(240, 100, 100, &r, &g, &b);
|
||||
assert(r == 0 && g == 0 && b == 255);
|
||||
/* Sector midpoints. Catches inverted ramp direction (k & 1 ? 1-f : f) in any single
|
||||
* sector — a regression would shift exactly one channel by ±half-intensity. */
|
||||
hsv_to_rgb(30, 100, 100, &r, &g, &b); /* orange — sector 0 */
|
||||
ASSERT_EQ(r, 255); ASSERT_EQ(g, 127); ASSERT_EQ(b, 0);
|
||||
hsv_to_rgb(90, 100, 100, &r, &g, &b); /* chartreuse — sector 1 */
|
||||
ASSERT_EQ(r, 127); ASSERT_EQ(g, 255); ASSERT_EQ(b, 0);
|
||||
hsv_to_rgb(150, 100, 100, &r, &g, &b); /* spring green — sector 2 */
|
||||
ASSERT_EQ(r, 0); ASSERT_EQ(g, 255); ASSERT_EQ(b, 127);
|
||||
hsv_to_rgb(210, 100, 100, &r, &g, &b); /* azure — sector 3 */
|
||||
ASSERT_EQ(r, 0); ASSERT_EQ(g, 127); ASSERT_EQ(b, 255);
|
||||
hsv_to_rgb(270, 100, 100, &r, &g, &b); /* violet — sector 4 */
|
||||
ASSERT_EQ(r, 127); ASSERT_EQ(g, 0); ASSERT_EQ(b, 255);
|
||||
hsv_to_rgb(330, 100, 100, &r, &g, &b); /* rose — sector 5 */
|
||||
ASSERT_EQ(r, 255); ASSERT_EQ(g, 0); ASSERT_EQ(b, 127);
|
||||
|
||||
/* Just below 360 — ensures (int) seg stays in sector 5 and doesn't wrap to 6. */
|
||||
hsv_to_rgb(359.5, 100, 100, &r, &g, &b);
|
||||
ASSERT_EQ(r, 255); ASSERT_EQ(g, 0); ASSERT_EQ(b, 2);
|
||||
|
||||
/* Exactly 360 — cyclic boundary, equivalent to 0 (red). Callers like color_for_pcr() in
|
||||
* pcrlock.c can reach this via floating-point arithmetic (e.g. 360.0/23*23 == 360.0). */
|
||||
hsv_to_rgb(360, 100, 100, &r, &g, &b);
|
||||
ASSERT_EQ(r, 255); ASSERT_EQ(g, 0); ASSERT_EQ(b, 0);
|
||||
|
||||
/* Non-trivial s/v: regression check for the multiply-and-cast path. */
|
||||
hsv_to_rgb(311, 52, 62, &r, &g, &b);
|
||||
assert(r == 158 && g == 75 && b == 143);
|
||||
ASSERT_EQ(r, 158); ASSERT_EQ(g, 75); ASSERT_EQ(b, 143);
|
||||
}
|
||||
|
||||
TEST(rgb_to_hsv) {
|
||||
|
||||
double h, s, v;
|
||||
|
||||
/* Grayscale: delta == 0, h is NaN, s == 0. */
|
||||
rgb_to_hsv(0, 0, 0, &h, &s, &v);
|
||||
assert(s <= 0);
|
||||
assert(v <= 0);
|
||||
ASSERT_TRUE(s <= 0);
|
||||
ASSERT_TRUE(v <= 0);
|
||||
|
||||
rgb_to_hsv(1, 1, 1, &h, &s, &v);
|
||||
assert(s <= 0);
|
||||
assert(v >= 100);
|
||||
ASSERT_TRUE(s <= 0);
|
||||
ASSERT_TRUE(v >= 100);
|
||||
|
||||
rgb_to_hsv(1, 0, 0, &h, &s, &v);
|
||||
assert(h >= 359 || h <= 1);
|
||||
assert(s >= 100);
|
||||
assert(v >= 100);
|
||||
rgb_to_hsv(0.5, 0.5, 0.5, &h, &s, &v);
|
||||
ASSERT_TRUE(s <= 0);
|
||||
ASSERT_TRUE(v >= 49 && v <= 51);
|
||||
|
||||
rgb_to_hsv(0, 1, 0, &h, &s, &v);
|
||||
assert(h >= 119 && h <= 121);
|
||||
assert(s >= 100);
|
||||
assert(v >= 100);
|
||||
/* Pure primary colors. */
|
||||
rgb_to_hsv(1, 0, 0, &h, &s, &v); /* red */
|
||||
ASSERT_TRUE(h >= 0 && h <= 1);
|
||||
ASSERT_TRUE(s >= 100);
|
||||
ASSERT_TRUE(v >= 100);
|
||||
|
||||
rgb_to_hsv(0, 0, 1, &h, &s, &v);
|
||||
assert(h >= 239 && h <= 241);
|
||||
assert(s >= 100);
|
||||
assert(v >= 100);
|
||||
rgb_to_hsv(0, 1, 0, &h, &s, &v); /* green */
|
||||
ASSERT_TRUE(h >= 119 && h <= 121);
|
||||
ASSERT_TRUE(s >= 100);
|
||||
ASSERT_TRUE(v >= 100);
|
||||
|
||||
rgb_to_hsv(0, 0, 1, &h, &s, &v); /* blue */
|
||||
ASSERT_TRUE(h >= 239 && h <= 241);
|
||||
ASSERT_TRUE(s >= 100);
|
||||
ASSERT_TRUE(v >= 100);
|
||||
|
||||
/* Pure secondary colors — each exercises a different "max" branch. Magenta exercises
|
||||
* the negative-hue wrap from the r-max branch (raw value is -60). */
|
||||
rgb_to_hsv(1, 1, 0, &h, &s, &v); /* yellow — r-max branch, positive */
|
||||
ASSERT_TRUE(h >= 59 && h <= 61);
|
||||
ASSERT_TRUE(s >= 100);
|
||||
ASSERT_TRUE(v >= 100);
|
||||
|
||||
rgb_to_hsv(0, 1, 1, &h, &s, &v); /* cyan — g-max branch */
|
||||
ASSERT_TRUE(h >= 179 && h <= 181);
|
||||
ASSERT_TRUE(s >= 100);
|
||||
ASSERT_TRUE(v >= 100);
|
||||
|
||||
rgb_to_hsv(1, 0, 1, &h, &s, &v); /* magenta — r-max branch, wrapped */
|
||||
ASSERT_TRUE(h >= 299 && h <= 301);
|
||||
ASSERT_TRUE(s >= 100);
|
||||
ASSERT_TRUE(v >= 100);
|
||||
|
||||
/* Mixed values. */
|
||||
rgb_to_hsv(0.5, 0.6, 0.7, &h, &s, &v);
|
||||
assert(h >= 209 && h <= 211);
|
||||
assert(s >= 28 && s <= 31);
|
||||
assert(v >= 69 && v <= 71);
|
||||
ASSERT_TRUE(h >= 209 && h <= 211);
|
||||
ASSERT_TRUE(s >= 28 && s <= 31);
|
||||
ASSERT_TRUE(v >= 69 && v <= 71);
|
||||
}
|
||||
|
||||
DEFINE_TEST_MAIN(LOG_DEBUG);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "acl-util.h"
|
||||
#include "apparmor-util.h"
|
||||
#include "blkid-util.h"
|
||||
#include "bpf-dlopen.h"
|
||||
#include "bpf-util.h"
|
||||
#include "compress.h"
|
||||
#include "crypto-util.h"
|
||||
#include "cryptsetup-util.h"
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "libcrypt-util.h"
|
||||
#include "libfido2-util.h"
|
||||
#include "libmount-util.h"
|
||||
#include "locale-util.h"
|
||||
#include "main-func.h"
|
||||
#include "microhttpd-util.h"
|
||||
#include "module-util.h"
|
||||
@@ -65,6 +66,7 @@ static int run(int argc, char **argv) {
|
||||
ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID);
|
||||
ASSERT_DLOPEN(dlopen_libcrypt, HAVE_LIBCRYPT);
|
||||
ASSERT_DLOPEN(dlopen_libfido2, HAVE_LIBFIDO2);
|
||||
ASSERT_OK(dlopen_libintl(LOG_DEBUG)); /* Required to be available at build time. */
|
||||
ASSERT_DLOPEN(dlopen_libkmod, HAVE_KMOD);
|
||||
ASSERT_DLOPEN(dlopen_libmount, HAVE_LIBMOUNT);
|
||||
ASSERT_DLOPEN(dlopen_libpam, HAVE_PAM);
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include <linux/netfilter/nf_tables.h>
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "capability-util.h"
|
||||
@@ -660,7 +659,7 @@ TEST(safe_atod) {
|
||||
ASSERT_ERROR(safe_atod("junk", &d), EINVAL);
|
||||
|
||||
ASSERT_OK_ZERO(safe_atod("0.2244", &d));
|
||||
assert_se(fabs(d - 0.2244) < 0.000001);
|
||||
assert_se(ABS(d - 0.2244) < 0.000001);
|
||||
|
||||
ASSERT_ERROR(safe_atod("0,5", &d), EINVAL);
|
||||
ASSERT_ERROR(safe_atod("", &d), EINVAL);
|
||||
@@ -672,7 +671,7 @@ TEST(safe_atod) {
|
||||
return (void) log_tests_skipped_errno(errno, "locale de_DE.utf8 not found");
|
||||
|
||||
ASSERT_OK_ZERO(safe_atod("0.2244", &d));
|
||||
assert_se(fabs(d - 0.2244) < 0.000001);
|
||||
assert_se(ABS(d - 0.2244) < 0.000001);
|
||||
|
||||
ASSERT_ERROR(safe_atod("0,5", &d), EINVAL);
|
||||
ASSERT_ERROR(safe_atod("", &d), EINVAL);
|
||||
|
||||
@@ -65,7 +65,7 @@ static void test_random_u64_range_one(unsigned mod) {
|
||||
i, count[i], dev,
|
||||
(int) (count[i] / scale), "x");
|
||||
|
||||
assert_se(fabs(dev) < 6); /* 6 sigma is excessive, but this check should be enough to
|
||||
assert_se(ABS(dev) < 6); /* 6 sigma is excessive, but this check should be enough to
|
||||
* identify catastrophic failure while minimizing false
|
||||
* positives. */
|
||||
}
|
||||
|
||||
@@ -35,10 +35,7 @@ executables += [
|
||||
'sources' : timesyncd_sources,
|
||||
'extract' : timesyncd_extract_sources,
|
||||
'link_with' : timesyncd_link_with,
|
||||
'dependencies' : [
|
||||
libm,
|
||||
threads,
|
||||
],
|
||||
'dependencies' : libm,
|
||||
},
|
||||
libexec_template + {
|
||||
'name' : 'systemd-time-wait-sync',
|
||||
|
||||
@@ -244,7 +244,7 @@ static int manager_adjust_clock(Manager *m, double offset, int leap_sec) {
|
||||
|
||||
/* For small deltas, tell the kernel to gradually adjust the system clock to the NTP time, larger
|
||||
* deltas are just directly set. */
|
||||
if (fabs(offset) < NTP_MAX_ADJUST) {
|
||||
if (ABS(offset) < NTP_MAX_ADJUST) {
|
||||
tmx = (struct timex) {
|
||||
.modes = ADJ_STATUS | ADJ_NANO | ADJ_OFFSET | ADJ_TIMECONST | ADJ_MAXERROR | ADJ_ESTERROR,
|
||||
.status = STA_PLL,
|
||||
@@ -346,7 +346,7 @@ static bool manager_sample_spike_detection(Manager *m, double offset, double del
|
||||
return false;
|
||||
|
||||
/* always accept offset if we are farther off than the round-trip delay */
|
||||
if (fabs(offset) > delay)
|
||||
if (ABS(offset) > delay)
|
||||
return false;
|
||||
|
||||
/* we need a few samples before looking at them */
|
||||
@@ -354,11 +354,11 @@ static bool manager_sample_spike_detection(Manager *m, double offset, double del
|
||||
return false;
|
||||
|
||||
/* do not accept anything worse than the maximum possible error of the best sample */
|
||||
if (fabs(offset) > m->samples[idx_min].delay)
|
||||
if (ABS(offset) > m->samples[idx_min].delay)
|
||||
return true;
|
||||
|
||||
/* compare the difference between the current offset to the previous offset and jitter */
|
||||
return fabs(offset - m->samples[idx_cur].offset) > 3 * jitter;
|
||||
return ABS(offset - m->samples[idx_cur].offset) > 3 * jitter;
|
||||
}
|
||||
|
||||
static void manager_adjust_poll(Manager *m, double offset, bool spike) {
|
||||
@@ -371,20 +371,20 @@ static void manager_adjust_poll(Manager *m, double offset, bool spike) {
|
||||
}
|
||||
|
||||
/* set to minimal poll interval */
|
||||
if (!spike && fabs(offset) > NTP_ACCURACY_SEC) {
|
||||
if (!spike && ABS(offset) > NTP_ACCURACY_SEC) {
|
||||
m->poll_interval_usec = m->poll_interval_min_usec;
|
||||
return;
|
||||
}
|
||||
|
||||
/* increase polling interval */
|
||||
if (fabs(offset) < NTP_ACCURACY_SEC * 0.25) {
|
||||
if (ABS(offset) < NTP_ACCURACY_SEC * 0.25) {
|
||||
if (m->poll_interval_usec < m->poll_interval_max_usec)
|
||||
m->poll_interval_usec *= 2;
|
||||
return;
|
||||
}
|
||||
|
||||
/* decrease polling interval */
|
||||
if (spike || fabs(offset) > NTP_ACCURACY_SEC * 0.75) {
|
||||
if (spike || ABS(offset) > NTP_ACCURACY_SEC * 0.75) {
|
||||
if (m->poll_interval_usec > m->poll_interval_min_usec)
|
||||
m->poll_interval_usec /= 2;
|
||||
return;
|
||||
|
||||
@@ -122,7 +122,6 @@ udev_dependencies = [
|
||||
libblkid_cflags,
|
||||
libkmod_cflags,
|
||||
libmount_cflags,
|
||||
threads,
|
||||
]
|
||||
|
||||
udev_plugin_template = executable_template + {
|
||||
@@ -138,7 +137,6 @@ udev_common_template = {
|
||||
'dependencies' : [
|
||||
libacl_cflags,
|
||||
libblkid_cflags,
|
||||
threads,
|
||||
],
|
||||
}
|
||||
udev_test_template = test_template + udev_common_template
|
||||
|
||||
@@ -5,7 +5,6 @@ executables += [
|
||||
'name' : 'systemd-userwork',
|
||||
'conditions' : ['ENABLE_USERDB'],
|
||||
'sources' : files('userwork.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
libexec_template + {
|
||||
'name' : 'systemd-userdbd',
|
||||
@@ -14,13 +13,11 @@ executables += [
|
||||
'userdbd-manager.c',
|
||||
'userdbd.c',
|
||||
),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
executable_template + {
|
||||
'name' : 'userdbctl',
|
||||
'conditions' : ['ENABLE_USERDB'],
|
||||
'sources' : files('userdbctl.c'),
|
||||
'dependencies' : threads,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user