endif
if HAVE_CRYPTSETUP
-if CRYPTSETUP_VIA_DLOPEN
edit_cmd += -e 's|@LIBCRYPTSETUP[@]||g'
edit_cmd += -e 's|@LIBDL[@]|-ldl|g'
else
-edit_cmd += -e 's|@LIBCRYPTSETUP[@]|libcryptsetup|g'
-edit_cmd += -e 's|@LIBDL[@]||g'
-endif
-else
edit_cmd += -e 's|@LIBCRYPTSETUP[@]||g'
edit_cmd += -e 's|@LIBDL[@]||g'
endif
AS_IF([test "x$with_cryptsetup" = xno], [
AM_CONDITIONAL([HAVE_CRYPTSETUP], [false])
- AM_CONDITIONAL([CRYPTSETUP_VIA_DLOPEN], [false])
], [
PKG_CHECK_MODULES([CRYPTSETUP], [libcryptsetup],
[AC_DEFINE([HAVE_CRYPTSETUP], [1], [Define if cryptsetup is available])
AC_CHECK_LIB([cryptsetup], [crypt_activate_by_signed_key], [
AC_DEFINE([HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY], [1], [Define if crypt_activate_by_signed_key exist in -lcryptsetup])
])
- AS_IF([test "x$with_cryptsetup" = xdlopen], [
- LIBS="-ldl $LIBS"
- AC_CHECK_LIB([dl], [dlsym], [
- AC_DEFINE([CRYPTSETUP_VIA_DLOPEN], [1], [Define if cryptsetup is to be loaded via dlopen])
- AM_CONDITIONAL([CRYPTSETUP_VIA_DLOPEN], [true])
- ], [AC_MSG_ERROR([libdl required to build with cryptsetup support])])
- ], [
- AM_CONDITIONAL([CRYPTSETUP_VIA_DLOPEN], [false])
- ])
CFLAGS="$SAVE_CFLAGS"
LIBS="$SAVE_LIBS"
have_cryptsetup=yes],
[have_cryptsetup=no
AM_CONDITIONAL([HAVE_CRYPTSETUP], [false])
- AM_CONDITIONAL([CRYPTSETUP_VIA_DLOPEN], [false])
])
AS_CASE([$with_cryptsetup:$have_cryptsetup],
include/c_strtod.h \
include/debug.h \
include/default_shell.h \
+ include/dl-cryptsetup.h \
include/dl-utils.h \
include/encode.h \
include/env.h \
--- /dev/null
+/*
+ * No copyright is claimed. This code is in the public domain; do with
+ * it what you wish.
+ */
+#ifndef UTIL_LINUX_DL_CRYPTSETUP_H
+#define UTIL_LINUX_DL_CRYPTSETUP_H
+
+#ifdef HAVE_CRYPTSETUP
+
+#include <libcryptsetup.h>
+
+#include "dl-utils.h"
+
+/* Pointers to libcryptsetup functions (initialized by dlsym()) */
+struct ul_cryptsetup_opers {
+ void (*crypt_set_debug_level)(int);
+ void (*crypt_set_log_callback)(struct crypt_device *,
+ void (*log)(int, const char *, void *), void *);
+ int (*crypt_init_data_device)(struct crypt_device **,
+ const char *, const char *);
+ int (*crypt_load)(struct crypt_device *, const char *, void *);
+ int (*crypt_get_volume_key_size)(struct crypt_device *);
+#ifdef HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
+ int (*crypt_activate_by_signed_key)(struct crypt_device *,
+ const char *, const char *, size_t,
+ const char *, size_t, uint32_t);
+#endif
+ int (*crypt_activate_by_volume_key)(struct crypt_device *,
+ const char *, const char *, size_t, uint32_t);
+ void (*crypt_free)(struct crypt_device *);
+ int (*crypt_init_by_name)(struct crypt_device **, const char *);
+ int (*crypt_get_verity_info)(struct crypt_device *,
+ struct crypt_params_verity *);
+ int (*crypt_volume_key_get)(struct crypt_device *, int,
+ char *, size_t *, const char *, size_t);
+ int (*crypt_deactivate_by_name)(struct crypt_device *,
+ const char *, uint32_t);
+};
+
+typedef struct ul_cryptsetup_opers ul_cryptsetup_opers;
+
+extern struct ul_cryptsetup_opers ul_cryptsetup;
+
+extern int ul_dlopen_libcryptsetup(void);
+
+#define cryptsetup_call(_func) (ul_cryptsetup._func)
+
+#endif /* HAVE_CRYPTSETUP */
+#endif /* UTIL_LINUX_DL_CRYPTSETUP_H */
--- /dev/null
+/*
+ * No copyright is claimed. This code is in the public domain; do with
+ * it what you wish.
+ */
+#include <dlfcn.h>
+
+#include "c.h"
+#include "dl-cryptsetup.h"
+
+#ifdef HAVE_CRYPTSETUP
+
+UL_ELF_NOTE_DLOPEN("cryptsetup",
+ "Support for dm-verity devices",
+ UL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
+ "libcryptsetup.so.12");
+
+struct ul_cryptsetup_opers ul_cryptsetup;
+
+static const struct ul_dlsym ul_cryptsetup_symbols[] =
+{
+ UL_DLSYM( ul_cryptsetup_opers, crypt_set_debug_level ),
+ UL_DLSYM( ul_cryptsetup_opers, crypt_set_log_callback ),
+ UL_DLSYM( ul_cryptsetup_opers, crypt_init_data_device ),
+ UL_DLSYM( ul_cryptsetup_opers, crypt_load ),
+ UL_DLSYM( ul_cryptsetup_opers, crypt_get_volume_key_size ),
+#ifdef HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
+ UL_DLSYM( ul_cryptsetup_opers, crypt_activate_by_signed_key ),
+#endif
+ UL_DLSYM( ul_cryptsetup_opers, crypt_activate_by_volume_key ),
+ UL_DLSYM( ul_cryptsetup_opers, crypt_free ),
+ UL_DLSYM( ul_cryptsetup_opers, crypt_init_by_name ),
+ UL_DLSYM( ul_cryptsetup_opers, crypt_get_verity_info ),
+ UL_DLSYM( ul_cryptsetup_opers, crypt_volume_key_get ),
+
+ UL_DLSYM( ul_cryptsetup_opers, crypt_deactivate_by_name ),
+};
+
+int ul_dlopen_libcryptsetup(void)
+{
+ /* 0 = not tried, 1 = loaded, -1 = failed */
+ static int status = 0;
+ static void *dl = NULL;
+ int flags = RTLD_LAZY | RTLD_LOCAL;
+
+ if (status)
+ return status > 0 ? 0 : -ENOSYS;
+
+#ifdef RTLD_NODELETE
+ flags |= RTLD_NODELETE;
+#endif
+#ifdef RTLD_DEEPBIND
+ flags |= RTLD_DEEPBIND;
+#endif
+ status = ul_dlopen_symbols("libcryptsetup.so.12", flags,
+ ul_cryptsetup_symbols,
+ ARRAY_SIZE(ul_cryptsetup_symbols),
+ &ul_cryptsetup, &dl) == 0 ? 1 : -1;
+
+ return status > 0 ? 0 : -ENOSYS;
+}
+
+#endif /* HAVE_CRYPTSETUP */
dependencies : lib_econf,
)
+dl_utils_c = files('dl-utils.c')
+dl_cryptsetup_c = files('dl-cryptsetup.c')
+
selinux_utils_c = files('selinux-utils.c')
caputils_c = files('caputils.c')
lib_mount_sources += 'src/btrfs.c'
endif
+if lib_cryptsetup.found()
+ lib_mount_sources += [dl_utils_c, dl_cryptsetup_c]
+endif
+
libmount_sym = 'src/libmount.sym'
libmount_sym_path = '@0@/@1@'.format(meson.current_source_dir(), libmount_sym)
error('neither dirfd nor ddfd are available')
endif
+lib__mount_compile_deps = [blkid_dep]
+if lib_cryptsetup.found()
+ lib__mount_compile_deps += lib_cryptsetup.partial_dependency(compile_args : true, includes : true)
+endif
+
lib__mount = static_library(
'_mount',
lib_mount_sources,
include_directories : [dir_include,
dir_libmount],
- dependencies : [blkid_dep])
+ dependencies : lib__mount_compile_deps)
lib_mount_static = static_library(
'mount_static',
lib__mount_deps = [
lib_selinux,
- cryptsetup_dlopen ? lib_dl : lib_cryptsetup,
+ lib_dl,
realtime_libs
]
$(REALTIME_LIBS)
if HAVE_CRYPTSETUP
-if CRYPTSETUP_VIA_DLOPEN
+libmount_la_SOURCES += \
+ lib/dl-utils.c \
+ include/dl-utils.h \
+ lib/dl-cryptsetup.c \
+ include/dl-cryptsetup.h
libmount_la_LIBADD += -ldl
-else
-libmount_la_LIBADD += $(CRYPTSETUP_LIBS)
-endif
endif
if USE_LIBMOUNT_UDEV_SUPPORT
libmount_la_CFLAGS = \
$(AM_CFLAGS) \
- $(SOLIB_CFLAGS) \
- $(CRYPTSETUP_CFLAGS) \
-I$(ul_libblkid_incdir) \
-I$(ul_libmount_incdir) \
- -I$(top_srcdir)/libmount/src
+ -I$(top_srcdir)/libmount/src \
+ $(SOLIB_CFLAGS) \
+ $(CRYPTSETUP_CFLAGS)
EXTRA_libmount_la_DEPENDENCIES = \
libmount/src/libmount.sym
endif
if HAVE_CRYPTSETUP
-if CRYPTSETUP_VIA_DLOPEN
libmount_tests_ldadd += -ldl
-else
-libmount_tests_ldadd += $(CRYPTSETUP_LIBS)
-endif
endif
test_mount_cache_SOURCES = libmount/src/cache.c
#ifdef HAVE_CRYPTSETUP
-#include <libcryptsetup.h>
+#include "dl-cryptsetup.h"
#include "path.h"
#include "strutils.h"
#include "fileutils.h"
#include "pathnames.h"
-#ifdef CRYPTSETUP_VIA_DLOPEN
-# include <dlfcn.h>
-
-/* Pointers to libcryptsetup functions (initialized by dlsym()) */
-struct verity_opers {
- void (*crypt_set_debug_level)(int);
- void (*crypt_set_log_callback)(struct crypt_device *, void (*log)(int, const char *, void *), void *);
- int (*crypt_init_data_device)(struct crypt_device **, const char *, const char *);
- int (*crypt_load)(struct crypt_device *, const char *, void *);
- int (*crypt_get_volume_key_size)(struct crypt_device *);
-# ifdef HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
- int (*crypt_activate_by_signed_key)(struct crypt_device *, const char *, const char *, size_t, const char *, size_t, uint32_t);
-# endif
- int (*crypt_activate_by_volume_key)(struct crypt_device *, const char *, const char *, size_t, uint32_t);
- void (*crypt_free)(struct crypt_device *);
- int (*crypt_init_by_name)(struct crypt_device **, const char *);
- int (*crypt_get_verity_info)(struct crypt_device *, struct crypt_params_verity *);
- int (*crypt_volume_key_get)(struct crypt_device *, int, char *, size_t *, const char *, size_t);
-
- int (*crypt_deactivate_by_name)(struct crypt_device *, const char *, uint32_t);
-};
-
-/* libcryptsetup functions names and offsets in 'struct verity_opers' */
-struct verity_sym {
- const char *name;
- size_t offset; /* offset of the symbol in verity_opers */
-};
-
-# define DEF_VERITY_SYM(_name) \
- { \
- .name = # _name, \
- .offset = offsetof(struct verity_opers, _name), \
- }
-
-/* All required symbols */
-static const struct verity_sym verity_symbols[] =
-{
- DEF_VERITY_SYM( crypt_set_debug_level ),
- DEF_VERITY_SYM( crypt_set_log_callback ),
- DEF_VERITY_SYM( crypt_init_data_device ),
- DEF_VERITY_SYM( crypt_load ),
- DEF_VERITY_SYM( crypt_get_volume_key_size ),
-# ifdef HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
- DEF_VERITY_SYM( crypt_activate_by_signed_key ),
-# endif
- DEF_VERITY_SYM( crypt_activate_by_volume_key ),
- DEF_VERITY_SYM( crypt_free ),
- DEF_VERITY_SYM( crypt_init_by_name ),
- DEF_VERITY_SYM( crypt_get_verity_info ),
- DEF_VERITY_SYM( crypt_volume_key_get ),
-
- DEF_VERITY_SYM( crypt_deactivate_by_name ),
-};
-#endif /* CRYPTSETUP_VIA_DLOPEN */
-
-
/* Data used by all verity hooks */
struct hookset_data {
char *devname; /* the device */
-#ifdef CRYPTSETUP_VIA_DLOPEN
- void *dl; /* dlopen() */
- struct verity_opers dl_funcs; /* dlsym() */
-#endif
};
-/* libcryptsetup call -- dlopen version requires 'struct hookset_data *hsd' */
-#ifdef CRYPTSETUP_VIA_DLOPEN
-# define verity_call(_func) (hsd->dl_funcs._func)
-#else
-# define verity_call(_func) (_func)
-#endif
+#define verity_call(_func) cryptsetup_call(_func)
static void delete_veritydev(struct libmnt_context *cxt,
struct hookset_data *hsd);
-#ifdef CRYPTSETUP_VIA_DLOPEN
-static int load_libcryptsetup_symbols(struct libmnt_context *cxt,
- struct hookset_data *hsd)
-{
- size_t i;
- const char *errmsg = NULL;
- int flags = RTLD_LAZY | RTLD_LOCAL;
-
- assert(cxt);
- assert(hsd);
- assert(hsd->dl == NULL);
-
- /* glibc extension: mnt_context_deferred_delete_veritydev is called immediately after, don't unload on dl_close */
-#ifdef RTLD_NODELETE
- flags |= RTLD_NODELETE;
-#endif
- /* glibc extension: might help to avoid further symbols clashes */
-#ifdef RTLD_DEEPBIND
- flags |= RTLD_DEEPBIND;
-#endif
- /* Don't rely on errno; the dlopen API may not use it. Also, note that
- * dlerror() provides complete messages that do not need any additional
- * introduction when printed to end users. */
- errno = 0;
-
- hsd->dl = dlopen("libcryptsetup.so.12", flags);
- if (!hsd->dl) {
- errmsg = dlerror();
- if (errmsg)
- mnt_context_sprintf_mesg(cxt, "e %s", errmsg);
- goto failed;
- }
-
- /* clear errors first, then load all the libcryptsetup symbols */
- dlerror();
-
- /* dlsym() */
- for (i = 0; i < ARRAY_SIZE(verity_symbols); i++) {
- const struct verity_sym *def = &verity_symbols[i];
- void **sym;
-
- sym = (void **) ((char *) (&hsd->dl_funcs) + def->offset);
- *sym = dlsym(hsd->dl, def->name);
-
- errmsg = dlerror();
- if (errmsg) {
- mnt_context_sprintf_mesg(cxt, "e %s", errmsg);
- goto failed;
- }
- }
- return 0;
-failed:
- if (!errno)
- errno = ENOTSUP;
- return -errno;
-}
-#endif
/* libcryptsetup callback */
static void libcryptsetup_log(int level __attribute__((__unused__)),
return;
if (hsd->devname)
delete_veritydev(cxt, hs, hsd);
-#ifdef CRYPTSETUP_VIA_DLOPEN
- if (hsd->dl)
- dlclose(hsd->dl);
-#endif
free(hsd);
mnt_context_set_hookset_data(cxt, hs, NULL);
}
{
struct hookset_data *hsd;
+ if (ul_dlopen_libcryptsetup() != 0)
+ return NULL;
+
hsd = calloc(1, sizeof(struct hookset_data));
if (!hsd)
return NULL;
if (mnt_context_set_hookset_data(cxt, hs, hsd) != 0)
goto failed;
-#ifdef CRYPTSETUP_VIA_DLOPEN
- if (load_libcryptsetup_symbols(cxt, hsd) != 0)
- goto failed;
-#endif
if (mnt_context_is_verbose(cxt))
verity_call( crypt_set_debug_level(CRYPT_DEBUG_ALL) );
required : get_option('cryptsetup'))
conf.set('HAVE_CRYPTSETUP', lib_cryptsetup.found() ? 1 : false)
-cryptsetup_dlopen = get_option('cryptsetup').allowed() and get_option('cryptsetup-dlopen').enabled()
-if cryptsetup_dlopen
- if meson.version().version_compare('>= 0.62.0')
- lib_dl = dependency('dl')
- else
- lib_dl = cc.find_library('dl')
- endif
- conf.set('CRYPTSETUP_VIA_DLOPEN', 1)
- summary('cryptsetup support (dlopen)',
- 'enabled',
- section : 'components')
+if meson.version().version_compare('>= 0.62.0')
+ lib_dl = dependency('dl')
else
- summary('cryptsetup support',
- lib_cryptsetup.found() ? 'enabled' : 'disabled',
- section : 'components')
+ lib_dl = cc.find_library('dl')
endif
+summary('cryptsetup support (dlopen)',
+ lib_cryptsetup.found() ? 'enabled' : 'disabled',
+ section : 'components')
+
have = cc.has_function(
'crypt_activate_by_signed_key',
dependencies : lib_cryptsetup)
option('slang', type : 'feature', value : 'disabled',
description : 'compile cfdisk with slang rather than ncurses')
option('cryptsetup', type : 'feature')
-option('cryptsetup-dlopen', type : 'feature')
+option('cryptsetup-dlopen', type : 'feature',
+ deprecated : true,
+ description : 'Deprecated, dlopen is now always used')
option('zlib', type : 'feature')
option('readline', type : 'feature')
option('nls', type : 'feature')