Merge pull request #32234 from poettering/dlopen-name-elf-note
Expose dlopen() dependencies in an ELF section, and add spec for it
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -39,3 +39,44 @@ int dlopen_many_sym_or_warn_sentinel(void **dlp, const char *filename, int log_l
|
||||
/* libbpf is a bit confused about type-safety and API compatibility. Provide a macro that can tape over that mess. Sad. */
|
||||
#define DLSYM_ARG_FORCE(arg) \
|
||||
&sym_##arg, STRINGIFY(arg)
|
||||
|
||||
#define ELF_NOTE_DLOPEN_VENDOR "FDO"
|
||||
#define ELF_NOTE_DLOPEN_TYPE UINT32_C(0x407c0c0a)
|
||||
#define ELF_NOTE_DLOPEN_PRIORITY_REQUIRED "required"
|
||||
#define ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED "recommended"
|
||||
#define ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED "suggested"
|
||||
|
||||
/* Add an ".note.dlopen" ELF note to our binary that declares our weak dlopen() dependency. This
|
||||
* information can be read from an ELF file via "readelf -p .note.dlopen" or an equivalent command. */
|
||||
#define _ELF_NOTE_DLOPEN(json, variable_name) \
|
||||
__attribute__((used, section(".note.dlopen"))) _Alignas(sizeof(uint32_t)) static const struct { \
|
||||
struct { \
|
||||
uint32_t n_namesz, n_descsz, n_type; \
|
||||
} nhdr; \
|
||||
char name[sizeof(ELF_NOTE_DLOPEN_VENDOR)]; \
|
||||
_Alignas(sizeof(uint32_t)) char dlopen_json[sizeof(json)]; \
|
||||
} variable_name = { \
|
||||
.nhdr = { \
|
||||
.n_namesz = sizeof(ELF_NOTE_DLOPEN_VENDOR), \
|
||||
.n_descsz = sizeof(json), \
|
||||
.n_type = ELF_NOTE_DLOPEN_TYPE, \
|
||||
}, \
|
||||
.name = ELF_NOTE_DLOPEN_VENDOR, \
|
||||
.dlopen_json = json, \
|
||||
}
|
||||
|
||||
#define _SONAME_ARRAY1(a) "[\""a"\"]"
|
||||
#define _SONAME_ARRAY2(a, b) "[\""a"\",\""b"\"]"
|
||||
#define _SONAME_ARRAY3(a, b, c) "[\""a"\",\""b"\",\""c"\"]"
|
||||
#define _SONAME_ARRAY4(a, b, c, d) "[\""a"\",\""b"\",\""c"\"",\""d"\"]"
|
||||
#define _SONAME_ARRAY5(a, b, c, d, e) "[\""a"\",\""b"\",\""c"\"",\""d"\",\""e"\"]"
|
||||
#define _SONAME_ARRAY_GET(_1,_2,_3,_4,_5,NAME,...) NAME
|
||||
#define _SONAME_ARRAY(...) _SONAME_ARRAY_GET(__VA_ARGS__, _SONAME_ARRAY5, _SONAME_ARRAY4, _SONAME_ARRAY3, _SONAME_ARRAY2, _SONAME_ARRAY1)(__VA_ARGS__)
|
||||
|
||||
/* The 'priority' must be one of 'required', 'recommended' or 'suggested' as per specification, use the
|
||||
* macro defined above to specify it.
|
||||
* Multiple sonames can be passed and they will be automatically contructed into a json array (but note that
|
||||
* due to preprocessor language limitations if more than the limit defined above is used, a new
|
||||
* _SONAME_ARRAY<X+1> will need to be added). */
|
||||
#define ELF_NOTE_DLOPEN(feature, description, priority, ...) \
|
||||
_ELF_NOTE_DLOPEN("[{\"feature\":\"" feature "\",\"description\":\"" description "\",\"priority\":\"" priority "\",\"soname\":" _SONAME_ARRAY(__VA_ARGS__) "}]", UNIQ_T(s, UNIQ))
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user