diff --git a/lib/internal.h b/lib/internal.h index 62622ec4..dc6dce02 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -58,6 +58,10 @@ void set_error(const char *fmt, ...); const char *get_error(void); /* Device mapper backend */ +#define DM_KEY_WIPE_SUPPORTED (1 << 0) /* kernel supports key wipe message */ +#define DM_LMK_SUPPORTED (1 << 1) /* kernel supports lmk mode */ +uint32_t dm_flags(void); + const char *dm_get_dir(void); int dm_init(struct crypt_device *context, int check_kernel); void dm_exit(void); @@ -93,6 +97,12 @@ int get_device_infos(const char *device, int open_exclusive, int *readonly, uint64_t *size); +int device_check_and_adjust(struct crypt_device *cd, + const char *device, + int open_exclusive, + uint64_t *size, + uint64_t *offset, + int *read_only); int wipe_device_header(const char *device, int sectors); void logger(struct crypt_device *cd, int class, const char *file, int line, const char *format, ...); diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c index 7a0dc420..7a5e8547 100644 --- a/lib/libdevmapper.c +++ b/lib/libdevmapper.c @@ -20,7 +20,7 @@ /* Set if dm-crypt version was probed */ static int _dm_crypt_checked = 0; -static int _dm_crypt_wipe_key_supported = 0; +static uint32_t _dm_crypt_flags = 0; static int _dm_use_count = 0; static struct crypt_device *_context = NULL; @@ -47,6 +47,11 @@ static int _dm_use_udev() #endif } +uint32_t dm_flags(void) +{ + return _dm_crypt_flags; +} + static void set_dm_error(int level, const char *file, int line, const char *f, ...) { @@ -72,10 +77,13 @@ static void _dm_set_crypt_compat(int maj, int min, int patch) log_dbg("Detected dm-crypt target of version %i.%i.%i.", maj, min, patch); if (maj >= 1 && min >=2) - _dm_crypt_wipe_key_supported = 1; + _dm_crypt_flags |= DM_KEY_WIPE_SUPPORTED; else log_dbg("Suspend and resume disabled, no wipe key support."); + if (maj >= 1 && min >=10) + _dm_crypt_flags |= DM_LMK_SUPPORTED; + _dm_crypt_checked = 1; } @@ -711,7 +719,7 @@ int dm_suspend_and_wipe_key(const char *name) if (!_dm_check_versions()) return -ENOTSUP; - if (!_dm_crypt_wipe_key_supported) + if (!(_dm_crypt_flags & DM_KEY_WIPE_SUPPORTED)) return -ENOTSUP; if (!_dm_simple(DM_DEVICE_SUSPEND, name, 0)) @@ -736,7 +744,7 @@ int dm_resume_and_reinstate_key(const char *name, if (!_dm_check_versions()) return -ENOTSUP; - if (!_dm_crypt_wipe_key_supported) + if (!(_dm_crypt_flags & DM_KEY_WIPE_SUPPORTED)) return -ENOTSUP; msg = crypt_safe_alloc(msg_size); diff --git a/lib/setup.c b/lib/setup.c index fd70ffe9..a4789865 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -246,52 +246,6 @@ out: return r; } -static int device_check_and_adjust(struct crypt_device *cd, - const char *device, - int open_exclusive, - uint64_t *size, - uint64_t *offset, - int *read_only) -{ - int r, real_readonly; - uint64_t real_size; - - if (!device) - return -ENOTBLK; - - r = get_device_infos(device, open_exclusive, &real_readonly, &real_size); - if (r < 0) { - if (r == -EBUSY) - log_err(cd, _("Cannot use device %s which is in use " - "(already mapped or mounted).\n"), - device); - else - log_err(cd, _("Cannot get info about device %s.\n"), - device); - return r; - } - - if (!*size) { - *size = real_size; - if (!*size) { - log_err(cd, _("Device %s has zero size.\n"), device); - return -ENOTBLK; - } - if (*size < *offset) { - log_err(cd, _("Device %s is too small.\n"), device); - return -EINVAL; - } - *size -= *offset; - } - - if (real_readonly) - *read_only = 1; - - log_dbg("Calculated device size is %" PRIu64 " sectors (%s), offset %" PRIu64 ".", - *size, *read_only ? "RO" : "RW", *offset); - return 0; -} - static int luks_remove_helper(struct crypt_device *cd, int key_slot, const char *other_key_file, diff --git a/lib/utils.c b/lib/utils.c index 34546911..d950a427 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -338,6 +338,52 @@ out: return r; } +int device_check_and_adjust(struct crypt_device *cd, + const char *device, + int open_exclusive, + uint64_t *size, + uint64_t *offset, + int *read_only) +{ + int r, real_readonly; + uint64_t real_size; + + if (!device) + return -ENOTBLK; + + r = get_device_infos(device, open_exclusive, &real_readonly, &real_size); + if (r < 0) { + if (r == -EBUSY) + log_err(cd, _("Cannot use device %s which is in use " + "(already mapped or mounted).\n"), + device); + else + log_err(cd, _("Cannot get info about device %s.\n"), + device); + return r; + } + + if (!*size) { + *size = real_size; + if (!*size) { + log_err(cd, _("Device %s has zero size.\n"), device); + return -ENOTBLK; + } + if (*size < *offset) { + log_err(cd, _("Device %s is too small.\n"), device); + return -EINVAL; + } + *size -= *offset; + } + + if (real_readonly) + *read_only = 1; + + log_dbg("Calculated device size is %" PRIu64 " sectors (%s), offset %" PRIu64 ".", + *size, *read_only ? "RO" : "RW", *offset); + return 0; +} + int wipe_device_header(const char *device, int sectors) { struct stat st; @@ -384,7 +430,7 @@ int crypt_memlock_inc(struct crypt_device *ctx) { if (!_memlock_count++) { log_dbg("Locking memory."); - if (mlockall(MCL_CURRENT | MCL_FUTURE)) { + if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) { log_err(ctx, _("WARNING!!! Possibly insecure memory. Are you root?\n")); _memlock_count--; return 0; @@ -394,7 +440,7 @@ int crypt_memlock_inc(struct crypt_device *ctx) log_err(ctx, _("Cannot get process priority.\n")); else if (setpriority(PRIO_PROCESS, 0, DEFAULT_PROCESS_PRIORITY)) - log_err(ctx, _("setpriority %u failed: %s"), + log_err(ctx, _("setpriority %d failed: %s\n"), DEFAULT_PROCESS_PRIORITY, strerror(errno)); } return _memlock_count ? 1 : 0; @@ -404,10 +450,10 @@ int crypt_memlock_dec(struct crypt_device *ctx) { if (_memlock_count && (!--_memlock_count)) { log_dbg("Unlocking memory."); - if (munlockall()) - log_err(ctx, _("Cannot unlock memory.")); + if (munlockall() == -1) + log_err(ctx, _("Cannot unlock memory.\n")); if (setpriority(PRIO_PROCESS, 0, _priority)) - log_err(ctx, _("setpriority %u failed: %s"), _priority, strerror(errno)); + log_err(ctx, _("setpriority %d failed: %s\n"), _priority, strerror(errno)); } return _memlock_count ? 1 : 0; }