block dlopen() once we transition into some foreign namespace (#39824)
Let's make sure we never accidentally end up loading code from a foreign namespace.
This commit is contained in:
+11
-8
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "bpf-dlopen.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "errno-util.h"
|
||||
#include "initrd-util.h"
|
||||
#include "log.h"
|
||||
|
||||
@@ -73,7 +74,6 @@ static int bpf_print_func(enum libbpf_print_level level, const char *fmt, va_lis
|
||||
}
|
||||
|
||||
int dlopen_bpf_full(int log_level) {
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
static int cached = 0;
|
||||
int r;
|
||||
|
||||
@@ -87,17 +87,20 @@ int dlopen_bpf_full(int log_level) {
|
||||
|
||||
DISABLE_WARNING_DEPRECATED_DECLARATIONS;
|
||||
|
||||
dl = dlopen("libbpf.so.1", RTLD_NOW|RTLD_NODELETE);
|
||||
if (!dl) {
|
||||
_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 */
|
||||
dl = dlopen("libbpf.so.0", RTLD_NOW|RTLD_NODELETE);
|
||||
if (!dl)
|
||||
return cached = 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: %s",
|
||||
dlerror());
|
||||
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()");
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "io-util.h"
|
||||
#include "iovec-util.h"
|
||||
#include "json-util.h"
|
||||
#include "libmount-util.h"
|
||||
#include "loop-util.h"
|
||||
#include "mkdir-label.h"
|
||||
#include "mount-util.h"
|
||||
@@ -3907,6 +3908,10 @@ int dissected_image_acquire_metadata(
|
||||
|
||||
assert(m);
|
||||
|
||||
r = dlopen_libmount();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (; n_meta_initialized < _META_MAX; n_meta_initialized++) {
|
||||
assert(paths[n_meta_initialized]);
|
||||
|
||||
|
||||
+13
-7
@@ -41,7 +41,6 @@ DLSYM_PROTOTYPE(stringprep_ucs4_to_utf8) = NULL;
|
||||
DLSYM_PROTOTYPE(stringprep_utf8_to_ucs4) = NULL;
|
||||
|
||||
int dlopen_idn(void) {
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
int r;
|
||||
|
||||
ELF_NOTE_DLOPEN("idn",
|
||||
@@ -52,14 +51,21 @@ int dlopen_idn(void) {
|
||||
if (idn_dl)
|
||||
return 0; /* Already loaded */
|
||||
|
||||
dl = dlopen("libidn.so.12", RTLD_NOW|RTLD_NODELETE);
|
||||
if (!dl) {
|
||||
r = check_dlopen_blocked("libidn.so.12");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
r = dlopen_safe("libidn.so.12", &dl, /* reterr_dlerror= */ NULL);
|
||||
if (r < 0) {
|
||||
/* libidn broke ABI in 1.34, but not in a way we care about (a new field got added to an
|
||||
* open-coded struct we do not use), hence support both versions. */
|
||||
dl = dlopen("libidn.so.11", RTLD_NOW|RTLD_NODELETE);
|
||||
if (!dl)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"libidn support is not installed: %s", dlerror());
|
||||
const char *dle = NULL;
|
||||
r = dlopen_safe("libidn.so.11", &dl, &dle);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "libidn support is not available: %s", dle ?: STRERROR(r));
|
||||
return -EOPNOTSUPP; /* turn into recognizable error */
|
||||
}
|
||||
log_debug("Loaded 'libidn.so.11' via dlopen()");
|
||||
} else
|
||||
log_debug("Loaded 'libidn.so.12' via dlopen()");
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "dirent-util.h"
|
||||
#include "dlfcn-util.h"
|
||||
#include "efi-api.h"
|
||||
#include "errno-util.h"
|
||||
#include "extract-word.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@@ -742,9 +743,12 @@ int tpm2_context_new(const char *device, Tpm2Context **ret_context) {
|
||||
if (!filename_is_valid(fn))
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EINVAL), "TPM2 driver name '%s' not valid, refusing.", driver);
|
||||
|
||||
context->tcti_dl = dlopen(fn, RTLD_NOW|RTLD_NODELETE);
|
||||
if (!context->tcti_dl)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENOPKG), "Failed to load %s: %s", fn, dlerror());
|
||||
const char *dle = NULL;
|
||||
r = dlopen_safe(fn, &context->tcti_dl, &dle);
|
||||
if (r < 0) {
|
||||
log_debug_errno(r, "Failed to load %s: %s", fn, dle ?: STRERROR(r));
|
||||
return -ENOPKG; /* Turn into recognizable error */
|
||||
}
|
||||
|
||||
log_debug("Loaded '%s' via dlopen()", fn);
|
||||
|
||||
|
||||
+7
-6
@@ -1977,21 +1977,22 @@ int membershipdb_by_group_strv(const char *name, UserDBFlags flags, char ***ret)
|
||||
}
|
||||
|
||||
int userdb_block_nss_systemd(int b) {
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
int (*call)(bool b);
|
||||
int r;
|
||||
|
||||
/* Note that we might be called from libnss_systemd.so.2 itself, but that should be fine, really. */
|
||||
|
||||
dl = dlopen(LIBDIR "/libnss_systemd.so.2", RTLD_NOW|RTLD_NODELETE);
|
||||
if (!dl) {
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
const char *dle;
|
||||
r = dlopen_safe(LIBDIR "/libnss_systemd.so.2", &dl, &dle);
|
||||
if (r < 0) {
|
||||
/* If the file isn't installed, don't complain loudly */
|
||||
log_debug("Failed to dlopen(libnss_systemd.so.2), ignoring: %s", dlerror());
|
||||
log_debug_errno(r, "Failed to dlopen(libnss_systemd.so.2), ignoring: %s", dle ?: STRERROR(r));
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug("Loaded '%s' via dlopen()", LIBDIR "/libnss_systemd.so.2");
|
||||
|
||||
call = dlsym(dl, "_nss_systemd_block");
|
||||
int (*call)(bool b) = dlsym(dl, "_nss_systemd_block");
|
||||
if (!call)
|
||||
/* If the file is installed but lacks the symbol we expect, things are weird, let's complain */
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ELIBBAD),
|
||||
|
||||
Reference in New Issue
Block a user