From cd7c2077954d86d23eafdedf3e258b365622779d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Apr 2024 17:50:41 +0200 Subject: [PATCH] tree-wide: add dlopen ELF notes to all dlopen() deps of ours Use 'recommended' priority for the default compression library, to indicate that it should be prioritized over the other ones, as it will be used to compress journals/core files. Also use 'recommended' for kmod, as systems will likely fail to boot if it's missing from the initrd. Use 'suggested' for everything else. There is one dlopen'ed TPM library that has the name generated at runtime (depending on the driver), so that cannot be added, as it needs to be known at build time. Also when we support multiple ABI versions list them all, as for the same reason we cannot know which one will be used at build time. $ dlopen-notes.py build/libsystemd.so.0.39.0 build/src/shared/libsystemd-shared-256.so libarchive.so.13 suggested libbpf.so.0 suggested libbpf.so.1 suggested libcryptsetup.so.12 suggested libdw.so.1 suggested libelf.so.1 suggested libfido2.so.1 suggested libgcrypt.so.20 suggested libidn2.so.0 suggested libip4tc.so.2 suggested libkmod.so.2 recommended liblz4.so.1 suggested liblzma.so.5 suggested libp11-kit.so.0 suggested libpcre2-8.so.0 suggested libpwquality.so.1 suggested libqrencode.so.3 suggested libqrencode.so.4 suggested libtss2-esys.so.0 suggested libtss2-mu.so.0 suggested libtss2-rc.so.0 suggested libzstd.so.1 recommended Co-authored-by: Luca Boccassi --- meson.build | 9 +++++++++ src/basic/compress.c | 15 +++++++++++++++ src/basic/gcrypt-util.c | 5 +++++ src/locale/xkbcommon-util.c | 4 ++++ src/shared/bpf-dlopen.c | 5 +++++ src/shared/cryptsetup-util.c | 5 +++++ src/shared/elf-util.c | 10 ++++++++++ src/shared/firewall-util-iptables.c | 5 +++++ src/shared/idn-util.c | 10 ++++++++++ src/shared/libarchive-util.c | 5 +++++ src/shared/libfido2-util.c | 5 +++++ src/shared/module-util.c | 5 +++++ src/shared/password-quality-util-passwdqc.c | 5 +++++ src/shared/password-quality-util-pwquality.c | 5 +++++ src/shared/pcre2-util.c | 5 +++++ src/shared/pkcs11-util.c | 5 +++++ src/shared/qrcode-util.c | 5 +++++ src/shared/tpm2-util.c | 15 +++++++++++++++ 18 files changed, 123 insertions(+) diff --git a/meson.build b/meson.build index 63c358194d8..6ea9fce85ad 100644 --- a/meson.build +++ b/meson.build @@ -1418,6 +1418,15 @@ elif compression == 'lz4' and not liblz4.found() elif compression == 'xz' and not libxz.found() error('default-compression=xz requires xz') endif +# In the dlopen ELF note we save the default compression library with a +# higher priority, so that packages can give it priority over the +# secondary libraries. +conf.set_quoted('COMPRESSION_PRIORITY_ZSTD', + compression == 'zstd' ? 'recommended' : 'suggested') +conf.set_quoted('COMPRESSION_PRIORITY_LZ4', + compression == 'lz4' ? 'recommended' : 'suggested') +conf.set_quoted('COMPRESSION_PRIORITY_XZ', + compression == 'xz' ? 'recommended' : 'suggested') conf.set('DEFAULT_COMPRESSION', 'COMPRESSION_@0@'.format(compression.to_upper())) libarchive = dependency('libarchive', diff --git a/src/basic/compress.c b/src/basic/compress.c index 5a4293fa814..33b27d3b99c 100644 --- a/src/basic/compress.c +++ b/src/basic/compress.c @@ -129,6 +129,11 @@ bool compression_supported(Compression c) { #if HAVE_XZ int dlopen_lzma(void) { + ELF_NOTE_DLOPEN("lzma", + "Support lzma compression in journal and coredump files", + COMPRESSION_PRIORITY_XZ, + "liblzma.so.5"); + return dlopen_many_sym_or_warn( &lzma_dl, "liblzma.so.5", LOG_DEBUG, @@ -186,6 +191,11 @@ int compress_blob_xz(const void *src, uint64_t src_size, #if HAVE_LZ4 int dlopen_lz4(void) { + ELF_NOTE_DLOPEN("lz4", + "Support lz4 compression in journal and coredump files", + COMPRESSION_PRIORITY_LZ4, + "liblz4.so.1"); + return dlopen_many_sym_or_warn( &lz4_dl, "liblz4.so.1", LOG_DEBUG, @@ -242,6 +252,11 @@ int compress_blob_lz4(const void *src, uint64_t src_size, #if HAVE_ZSTD int dlopen_zstd(void) { + ELF_NOTE_DLOPEN("zstd", + "Support zstd compression in journal and coredump files", + COMPRESSION_PRIORITY_ZSTD, + "libzstd.so.1"); + return dlopen_many_sym_or_warn( &zstd_dl, "libzstd.so.1", LOG_DEBUG, diff --git a/src/basic/gcrypt-util.c b/src/basic/gcrypt-util.c index 081866537c4..4d68d2c22b4 100644 --- a/src/basic/gcrypt-util.c +++ b/src/basic/gcrypt-util.c @@ -41,6 +41,11 @@ DLSYM_FUNCTION(gcry_randomize); DLSYM_FUNCTION(gcry_strerror); static int dlopen_gcrypt(void) { + ELF_NOTE_DLOPEN("gcrypt", + "Support for journald forward-sealing", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libgcrypt.so.20"); + return dlopen_many_sym_or_warn( &gcrypt_dl, "libgcrypt.so.20", LOG_DEBUG, diff --git a/src/locale/xkbcommon-util.c b/src/locale/xkbcommon-util.c index 468452f8afd..d4e24cd0dd2 100644 --- a/src/locale/xkbcommon-util.c +++ b/src/locale/xkbcommon-util.c @@ -16,6 +16,10 @@ DLSYM_FUNCTION(xkb_keymap_new_from_names); DLSYM_FUNCTION(xkb_keymap_unref); static int dlopen_xkbcommon(void) { + ELF_NOTE_DLOPEN("xkbcommon", + "Support for keyboard locale descriptions", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, "libxkbcommon.so.0"); + return dlopen_many_sym_or_warn( &xkbcommon_dl, "libxkbcommon.so.0", LOG_DEBUG, DLSYM_ARG(xkb_context_new), diff --git a/src/shared/bpf-dlopen.c b/src/shared/bpf-dlopen.c index de3e40516eb..d4ae24053eb 100644 --- a/src/shared/bpf-dlopen.c +++ b/src/shared/bpf-dlopen.c @@ -76,6 +76,11 @@ int dlopen_bpf(void) { void *dl; int r; + ELF_NOTE_DLOPEN("bpf", + "Support firewalling and sandboxing with BPF", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libbpf.so.1", "libbpf.so.0"); + DISABLE_WARNING_DEPRECATED_DECLARATIONS; dl = dlopen("libbpf.so.1", RTLD_LAZY); diff --git a/src/shared/cryptsetup-util.c b/src/shared/cryptsetup-util.c index cbbc85a5cc5..288e6e89425 100644 --- a/src/shared/cryptsetup-util.c +++ b/src/shared/cryptsetup-util.c @@ -252,6 +252,11 @@ int dlopen_cryptsetup(void) { DISABLE_WARNING_DEPRECATED_DECLARATIONS; + ELF_NOTE_DLOPEN("cryptsetup", + "Support for disk encryption, integrity, and authentication", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libcryptsetup.so.12"); + r = dlopen_many_sym_or_warn( &cryptsetup_dl, "libcryptsetup.so.12", LOG_DEBUG, DLSYM_ARG(crypt_activate_by_passphrase), diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c index 85f3c173db1..9d1f4946718 100644 --- a/src/shared/elf-util.c +++ b/src/shared/elf-util.c @@ -87,6 +87,11 @@ static DLSYM_FUNCTION(gelf_getnote); int dlopen_dw(void) { int r; + ELF_NOTE_DLOPEN("dw", + "Support for backtrace and ELF package metadata decoding from core files", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libdw.so.1"); + r = dlopen_many_sym_or_warn( &dw_dl, "libdw.so.1", LOG_DEBUG, DLSYM_ARG(dwarf_getscopes), @@ -130,6 +135,11 @@ int dlopen_dw(void) { int dlopen_elf(void) { int r; + ELF_NOTE_DLOPEN("elf", + "Support for backtraces and reading ELF package metadata from core files", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libelf.so.1"); + r = dlopen_many_sym_or_warn( &elf_dl, "libelf.so.1", LOG_DEBUG, DLSYM_ARG(elf_begin), diff --git a/src/shared/firewall-util-iptables.c b/src/shared/firewall-util-iptables.c index 044d2d07447..b0abccc26bd 100644 --- a/src/shared/firewall-util-iptables.c +++ b/src/shared/firewall-util-iptables.c @@ -354,6 +354,11 @@ int fw_iptables_add_local_dnat( } static int dlopen_iptc(void) { + ELF_NOTE_DLOPEN("ip4tc", + "Support for firewall rules", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libip4tc.so.2"); + return dlopen_many_sym_or_warn( &iptc_dl, "libip4tc.so.2", LOG_DEBUG, diff --git a/src/shared/idn-util.c b/src/shared/idn-util.c index 6b26f2064a1..aa88e112217 100644 --- a/src/shared/idn-util.c +++ b/src/shared/idn-util.c @@ -21,6 +21,11 @@ const char *(*sym_idn2_strerror)(int rc) _const_ = NULL; DLSYM_FUNCTION(idn2_to_unicode_8z8z); int dlopen_idn(void) { + ELF_NOTE_DLOPEN("idn", + "Support for internationalized domain names", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libidn2.so.0"); + return dlopen_many_sym_or_warn( &idn_dl, "libidn2.so.0", LOG_DEBUG, DLSYM_ARG(idn2_lookup_u8), @@ -39,6 +44,11 @@ int dlopen_idn(void) { _cleanup_(dlclosep) void *dl = NULL; int r; + ELF_NOTE_DLOPEN("idn", + "Support for internationalized domain names", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libidn.so.12", "libidn.so.11"); + if (idn_dl) return 0; /* Already loaded */ diff --git a/src/shared/libarchive-util.c b/src/shared/libarchive-util.c index e6d65815970..58f6554da27 100644 --- a/src/shared/libarchive-util.c +++ b/src/shared/libarchive-util.c @@ -30,6 +30,11 @@ DLSYM_FUNCTION(archive_write_set_format_filter_by_ext); DLSYM_FUNCTION(archive_write_set_format_gnutar); int dlopen_libarchive(void) { + ELF_NOTE_DLOPEN("archive", + "Support for decompressing archive files", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libarchive.so.13"); + return dlopen_many_sym_or_warn( &libarchive_dl, "libarchive.so.13", diff --git a/src/shared/libfido2-util.c b/src/shared/libfido2-util.c index 17fb019ffce..37f68989255 100644 --- a/src/shared/libfido2-util.c +++ b/src/shared/libfido2-util.c @@ -72,6 +72,11 @@ static void fido_log_propagate_handler(const char *s) { int dlopen_libfido2(void) { int r; + ELF_NOTE_DLOPEN("fido2", + "Support fido2 for encryption and authentication", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libfido2.so.1"); + r = dlopen_many_sym_or_warn( &libfido2_dl, "libfido2.so.1", LOG_DEBUG, DLSYM_ARG(fido_assert_allow_cred), diff --git a/src/shared/module-util.c b/src/shared/module-util.c index 612ab9c9c5f..fa1e0f82bb0 100644 --- a/src/shared/module-util.c +++ b/src/shared/module-util.c @@ -25,6 +25,11 @@ DLSYM_FUNCTION(kmod_unref); DLSYM_FUNCTION(kmod_validate_resources); int dlopen_libkmod(void) { + ELF_NOTE_DLOPEN("kmod", + "Support for loading kernel modules", + ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED, + "libkmod.so.2"); + return dlopen_many_sym_or_warn( &libkmod_dl, "libkmod.so.2", diff --git a/src/shared/password-quality-util-passwdqc.c b/src/shared/password-quality-util-passwdqc.c index c32b4935345..764b7724b00 100644 --- a/src/shared/password-quality-util-passwdqc.c +++ b/src/shared/password-quality-util-passwdqc.c @@ -20,6 +20,11 @@ DLSYM_FUNCTION(passwdqc_check); DLSYM_FUNCTION(passwdqc_random); int dlopen_passwdqc(void) { + ELF_NOTE_DLOPEN("passwdqc", + "Support for password quality checks", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libpasswdqc.so.1"); + return dlopen_many_sym_or_warn( &passwdqc_dl, "libpasswdqc.so.1", LOG_DEBUG, DLSYM_ARG(passwdqc_params_reset), diff --git a/src/shared/password-quality-util-pwquality.c b/src/shared/password-quality-util-pwquality.c index e070f9636c6..7456469c86e 100644 --- a/src/shared/password-quality-util-pwquality.c +++ b/src/shared/password-quality-util-pwquality.c @@ -24,6 +24,11 @@ DLSYM_FUNCTION(pwquality_set_int_value); DLSYM_FUNCTION(pwquality_strerror); int dlopen_pwquality(void) { + ELF_NOTE_DLOPEN("pwquality", + "Support for password quality checks", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libpwquality.so.1"); + return dlopen_many_sym_or_warn( &pwquality_dl, "libpwquality.so.1", LOG_DEBUG, DLSYM_ARG(pwquality_check), diff --git a/src/shared/pcre2-util.c b/src/shared/pcre2-util.c index 4f33efc5fc9..7deb64fd498 100644 --- a/src/shared/pcre2-util.c +++ b/src/shared/pcre2-util.c @@ -27,6 +27,11 @@ const struct hash_ops pcre2_code_hash_ops_free = {}; int dlopen_pcre2(void) { #if HAVE_PCRE2 + ELF_NOTE_DLOPEN("pcre2", + "Support for regular expressions", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libpcre2-8.so.0"); + /* So here's something weird: PCRE2 actually renames the symbols exported by the library via C * macros, so that the exported symbols carry a suffix "_8" but when used from C the suffix is * gone. In the argument list below we ignore this mangling. Surprisingly (at least to me), we diff --git a/src/shared/pkcs11-util.c b/src/shared/pkcs11-util.c index 8077ec3019d..b5cd9a35bb2 100644 --- a/src/shared/pkcs11-util.c +++ b/src/shared/pkcs11-util.c @@ -61,6 +61,11 @@ DLSYM_FUNCTION(p11_kit_uri_new); DLSYM_FUNCTION(p11_kit_uri_parse); int dlopen_p11kit(void) { + ELF_NOTE_DLOPEN("p11-kit", + "Support for PKCS11 hardware tokens", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libp11-kit.so.0"); + return dlopen_many_sym_or_warn( &p11kit_dl, "libp11-kit.so.0", LOG_DEBUG, diff --git a/src/shared/qrcode-util.c b/src/shared/qrcode-util.c index c087136bd2b..e62a5a86358 100644 --- a/src/shared/qrcode-util.c +++ b/src/shared/qrcode-util.c @@ -24,6 +24,11 @@ static DLSYM_FUNCTION(QRcode_free); int dlopen_qrencode(void) { int r; + ELF_NOTE_DLOPEN("qrencode", + "Support for generating QR codes", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libqrencode.so.4", "libqrencode.so.3"); + FOREACH_STRING(s, "libqrencode.so.4", "libqrencode.so.3") { r = dlopen_many_sym_or_warn( &qrcode_dl, s, LOG_DEBUG, diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index 3afeb095169..a64c2738bf2 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -113,6 +113,11 @@ static DLSYM_FUNCTION(Tss2_RC_Decode); int dlopen_tpm2(void) { int r; + ELF_NOTE_DLOPEN("tpm", + "Support for TPM", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libtss2-esys.so.0"); + r = dlopen_many_sym_or_warn( &libtss2_esys_dl, "libtss2-esys.so.0", LOG_DEBUG, DLSYM_ARG(Esys_Create), @@ -164,12 +169,22 @@ int dlopen_tpm2(void) { if (r < 0) log_debug("libtss2-esys too old, does not include Esys_TR_GetTpmHandle."); + ELF_NOTE_DLOPEN("tpm", + "Support for TPM", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libtss2-rc.so.0"); + r = dlopen_many_sym_or_warn( &libtss2_rc_dl, "libtss2-rc.so.0", LOG_DEBUG, DLSYM_ARG(Tss2_RC_Decode)); if (r < 0) return r; + ELF_NOTE_DLOPEN("tpm", + "Support for TPM", + ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED, + "libtss2-mu.so.0"); + return dlopen_many_sym_or_warn( &libtss2_mu_dl, "libtss2-mu.so.0", LOG_DEBUG, DLSYM_ARG(Tss2_MU_TPM2_CC_Marshal),