2 * libdevmapper - device-mapper backend for cryptsetup
4 * Copyright (C) 2004 Jana Saout <jana@saout.de>
5 * Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
6 * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
7 * Copyright (C) 2009-2021 Milan Broz
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 #include <libdevmapper.h>
31 #include <uuid/uuid.h>
33 #ifdef HAVE_SYS_SYSMACROS_H
34 # include <sys/sysmacros.h> /* for major, minor */
39 #define DM_UUID_LEN 129
40 #define DM_BY_ID_PREFIX "dm-uuid-"
41 #define DM_BY_ID_PREFIX_LEN 8
42 #define DM_UUID_PREFIX "CRYPT-"
43 #define DM_UUID_PREFIX_LEN 6
44 #define DM_CRYPT_TARGET "crypt"
45 #define DM_VERITY_TARGET "verity"
46 #define DM_INTEGRITY_TARGET "integrity"
47 #define DM_LINEAR_TARGET "linear"
48 #define DM_ERROR_TARGET "error"
49 #define DM_ZERO_TARGET "zero"
52 /* Set if DM target versions were probed */
53 static bool _dm_ioctl_checked = false;
54 static bool _dm_crypt_checked = false;
55 static bool _dm_verity_checked = false;
56 static bool _dm_integrity_checked = false;
58 static int _quiet_log = 0;
59 static uint32_t _dm_flags = 0;
61 static struct crypt_device *_context = NULL;
62 static int _dm_use_count = 0;
64 /* Check if we have DM flag to instruct kernel to force wipe buffers */
65 #if !HAVE_DECL_DM_TASK_SECURE_DATA
66 static int dm_task_secure_data(struct dm_task *dmt) { return 1; }
69 /* Compatibility for old device-mapper without udev support */
70 #if HAVE_DECL_DM_UDEV_DISABLE_DISK_RULES_FLAG
71 #define CRYPT_TEMP_UDEV_FLAGS DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG | \
72 DM_UDEV_DISABLE_DISK_RULES_FLAG | \
73 DM_UDEV_DISABLE_OTHER_RULES_FLAG
74 #define _dm_task_set_cookie dm_task_set_cookie
75 #define _dm_udev_wait dm_udev_wait
77 #define CRYPT_TEMP_UDEV_FLAGS 0
78 static int _dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) { return 0; }
79 static int _dm_udev_wait(uint32_t cookie) { return 0; };
82 static int _dm_use_udev(void)
84 #ifdef USE_UDEV /* cannot be enabled if devmapper is too old */
85 return dm_udev_get_sync_support();
91 __attribute__((format(printf, 4, 5)))
92 static void set_dm_error(int level,
93 const char *file __attribute__((unused)),
94 int line __attribute__((unused)),
101 if (vasprintf(&msg, f, va) > 0) {
102 if (level < 4 && !_quiet_log) {
103 log_err(_context, "%s", msg);
105 /* We do not use DM visual stack backtrace here */
106 if (strncmp(msg, "<backtrace>", 11))
107 log_dbg(_context, "%s", msg);
114 static int _dm_satisfies_version(unsigned target_maj, unsigned target_min, unsigned target_patch,
115 unsigned actual_maj, unsigned actual_min, unsigned actual_patch)
117 if (actual_maj > target_maj)
120 if (actual_maj == target_maj && actual_min > target_min)
123 if (actual_maj == target_maj && actual_min == target_min && actual_patch >= target_patch)
129 static void _dm_set_crypt_compat(struct crypt_device *cd,
132 unsigned crypt_patch)
134 if (_dm_crypt_checked || crypt_maj == 0)
137 log_dbg(cd, "Detected dm-crypt version %i.%i.%i.",
138 crypt_maj, crypt_min, crypt_patch);
140 if (_dm_satisfies_version(1, 2, 0, crypt_maj, crypt_min, crypt_patch))
141 _dm_flags |= DM_KEY_WIPE_SUPPORTED;
143 log_dbg(cd, "Suspend and resume disabled, no wipe key support.");
145 if (_dm_satisfies_version(1, 10, 0, crypt_maj, crypt_min, crypt_patch))
146 _dm_flags |= DM_LMK_SUPPORTED;
148 /* not perfect, 2.6.33 supports with 1.7.0 */
149 if (_dm_satisfies_version(1, 8, 0, crypt_maj, crypt_min, crypt_patch))
150 _dm_flags |= DM_PLAIN64_SUPPORTED;
152 if (_dm_satisfies_version(1, 11, 0, crypt_maj, crypt_min, crypt_patch))
153 _dm_flags |= DM_DISCARDS_SUPPORTED;
155 if (_dm_satisfies_version(1, 13, 0, crypt_maj, crypt_min, crypt_patch))
156 _dm_flags |= DM_TCW_SUPPORTED;
158 if (_dm_satisfies_version(1, 14, 0, crypt_maj, crypt_min, crypt_patch)) {
159 _dm_flags |= DM_SAME_CPU_CRYPT_SUPPORTED;
160 _dm_flags |= DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED;
163 if (_dm_satisfies_version(1, 18, 1, crypt_maj, crypt_min, crypt_patch))
164 _dm_flags |= DM_KERNEL_KEYRING_SUPPORTED;
166 if (_dm_satisfies_version(1, 17, 0, crypt_maj, crypt_min, crypt_patch)) {
167 _dm_flags |= DM_SECTOR_SIZE_SUPPORTED;
168 _dm_flags |= DM_CAPI_STRING_SUPPORTED;
171 if (_dm_satisfies_version(1, 19, 0, crypt_maj, crypt_min, crypt_patch))
172 _dm_flags |= DM_BITLK_EBOIV_SUPPORTED;
174 if (_dm_satisfies_version(1, 20, 0, crypt_maj, crypt_min, crypt_patch))
175 _dm_flags |= DM_BITLK_ELEPHANT_SUPPORTED;
177 if (_dm_satisfies_version(1, 22, 0, crypt_maj, crypt_min, crypt_patch))
178 _dm_flags |= DM_CRYPT_NO_WORKQUEUE_SUPPORTED;
180 _dm_crypt_checked = true;
183 static void _dm_set_verity_compat(struct crypt_device *cd,
186 unsigned verity_patch)
188 if (_dm_verity_checked || verity_maj == 0)
191 log_dbg(cd, "Detected dm-verity version %i.%i.%i.",
192 verity_maj, verity_min, verity_patch);
194 _dm_flags |= DM_VERITY_SUPPORTED;
197 * ignore_corruption, restart_on corruption is available since 1.2 (kernel 4.1)
198 * ignore_zero_blocks since 1.3 (kernel 4.5)
199 * (but some dm-verity targets 1.2 don't support it)
200 * FEC is added in 1.3 as well.
201 * Check at most once is added in 1.4 (kernel 4.17).
203 if (_dm_satisfies_version(1, 3, 0, verity_maj, verity_min, verity_patch)) {
204 _dm_flags |= DM_VERITY_ON_CORRUPTION_SUPPORTED;
205 _dm_flags |= DM_VERITY_FEC_SUPPORTED;
208 if (_dm_satisfies_version(1, 5, 0, verity_maj, verity_min, verity_patch))
209 _dm_flags |= DM_VERITY_SIGNATURE_SUPPORTED;
211 if (_dm_satisfies_version(1, 7, 0, verity_maj, verity_min, verity_patch))
212 _dm_flags |= DM_VERITY_PANIC_CORRUPTION_SUPPORTED;
214 _dm_verity_checked = true;
217 static void _dm_set_integrity_compat(struct crypt_device *cd,
218 unsigned integrity_maj,
219 unsigned integrity_min,
220 unsigned integrity_patch)
222 if (_dm_integrity_checked || integrity_maj == 0)
225 log_dbg(cd, "Detected dm-integrity version %i.%i.%i.",
226 integrity_maj, integrity_min, integrity_patch);
228 _dm_flags |= DM_INTEGRITY_SUPPORTED;
230 if (_dm_satisfies_version(1, 2, 0, integrity_maj, integrity_min, integrity_patch))
231 _dm_flags |= DM_INTEGRITY_RECALC_SUPPORTED;
233 if (_dm_satisfies_version(1, 3, 0, integrity_maj, integrity_min, integrity_patch))
234 _dm_flags |= DM_INTEGRITY_BITMAP_SUPPORTED;
236 if (_dm_satisfies_version(1, 4, 0, integrity_maj, integrity_min, integrity_patch))
237 _dm_flags |= DM_INTEGRITY_FIX_PADDING_SUPPORTED;
239 if (_dm_satisfies_version(1, 6, 0, integrity_maj, integrity_min, integrity_patch))
240 _dm_flags |= DM_INTEGRITY_DISCARDS_SUPPORTED;
242 if (_dm_satisfies_version(1, 7, 0, integrity_maj, integrity_min, integrity_patch))
243 _dm_flags |= DM_INTEGRITY_FIX_HMAC_SUPPORTED;
245 _dm_integrity_checked = true;
248 /* We use this for loading target module */
249 static void _dm_check_target(dm_target_type target_type)
251 #if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
253 const char *target_name = NULL;
255 if (!(_dm_flags & DM_GET_TARGET_VERSION_SUPPORTED))
258 if (target_type == DM_CRYPT)
259 target_name = DM_CRYPT_TARGET;
260 else if (target_type == DM_VERITY)
261 target_name = DM_VERITY_TARGET;
262 else if (target_type == DM_INTEGRITY)
263 target_name = DM_INTEGRITY_TARGET;
267 if (!(dmt = dm_task_create(DM_DEVICE_GET_TARGET_VERSION)))
270 if (!dm_task_set_name(dmt, target_name))
273 if (!dm_task_run(dmt))
277 dm_task_destroy(dmt);
281 static int _dm_check_versions(struct crypt_device *cd, dm_target_type target_type)
284 struct dm_versions *target, *last_target;
286 unsigned dm_maj, dm_min, dm_patch;
289 if ((target_type == DM_CRYPT && _dm_crypt_checked) ||
290 (target_type == DM_VERITY && _dm_verity_checked) ||
291 (target_type == DM_INTEGRITY && _dm_integrity_checked) ||
292 (target_type == DM_LINEAR) || (target_type == DM_ZERO) ||
293 (_dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked))
296 /* Shut up DM while checking */
299 _dm_check_target(target_type);
301 /* FIXME: add support to DM so it forces crypt target module load here */
302 if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
305 if (!dm_task_run(dmt))
308 if (!dm_task_get_driver_version(dmt, dm_version, sizeof(dm_version)))
311 if (!_dm_ioctl_checked) {
312 if (sscanf(dm_version, "%u.%u.%u", &dm_maj, &dm_min, &dm_patch) != 3)
314 log_dbg(cd, "Detected dm-ioctl version %u.%u.%u.", dm_maj, dm_min, dm_patch);
316 if (_dm_satisfies_version(4, 20, 0, dm_maj, dm_min, dm_patch))
317 _dm_flags |= DM_SECURE_SUPPORTED;
318 #if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
319 if (_dm_satisfies_version(4, 27, 0, dm_maj, dm_min, dm_patch))
320 _dm_flags |= DM_DEFERRED_SUPPORTED;
322 #if HAVE_DECL_DM_DEVICE_GET_TARGET_VERSION
323 if (_dm_satisfies_version(4, 41, 0, dm_maj, dm_min, dm_patch))
324 _dm_flags |= DM_GET_TARGET_VERSION_SUPPORTED;
328 target = dm_task_get_versions(dmt);
330 last_target = target;
331 if (!strcmp(DM_CRYPT_TARGET, target->name)) {
332 _dm_set_crypt_compat(cd, (unsigned)target->version[0],
333 (unsigned)target->version[1],
334 (unsigned)target->version[2]);
335 } else if (!strcmp(DM_VERITY_TARGET, target->name)) {
336 _dm_set_verity_compat(cd, (unsigned)target->version[0],
337 (unsigned)target->version[1],
338 (unsigned)target->version[2]);
339 } else if (!strcmp(DM_INTEGRITY_TARGET, target->name)) {
340 _dm_set_integrity_compat(cd, (unsigned)target->version[0],
341 (unsigned)target->version[1],
342 (unsigned)target->version[2]);
344 target = (struct dm_versions *)((char *) target + target->next);
345 } while (last_target != target);
348 if (!_dm_ioctl_checked)
349 log_dbg(cd, "Device-mapper backend running with UDEV support %sabled.",
350 _dm_use_udev() ? "en" : "dis");
352 _dm_ioctl_checked = true;
355 dm_task_destroy(dmt);
361 int dm_flags(struct crypt_device *cd, dm_target_type target, uint32_t *flags)
363 _dm_check_versions(cd, target);
366 if (target == DM_UNKNOWN &&
367 _dm_crypt_checked && _dm_verity_checked && _dm_integrity_checked)
370 if ((target == DM_CRYPT && _dm_crypt_checked) ||
371 (target == DM_VERITY && _dm_verity_checked) ||
372 (target == DM_INTEGRITY && _dm_integrity_checked) ||
373 (target == DM_LINEAR) || (target == DM_ZERO)) /* nothing to check */
379 /* This doesn't run any kernel checks, just set up userspace libdevmapper */
380 void dm_backend_init(struct crypt_device *cd)
382 if (!_dm_use_count++) {
383 log_dbg(cd, "Initialising device-mapper backend library.");
384 dm_log_init(set_dm_error);
385 dm_log_init_verbose(10);
389 void dm_backend_exit(struct crypt_device *cd)
391 if (_dm_use_count && (!--_dm_use_count)) {
392 log_dbg(cd, "Releasing device-mapper backend.");
393 dm_log_init_verbose(0);
400 * libdevmapper is not context friendly, switch context on every DM call.
401 * FIXME: this is not safe if called in parallel but neither is DM lib.
403 static int dm_init_context(struct crypt_device *cd, dm_target_type target)
406 if (!_dm_check_versions(cd, target)) {
407 if (getuid() || geteuid())
408 log_err(cd, _("Cannot initialize device-mapper, "
409 "running as non-root user."));
411 log_err(cd, _("Cannot initialize device-mapper. "
412 "Is dm_mod kernel module loaded?"));
418 static void dm_exit_context(void)
423 /* Return path to DM device */
424 char *dm_device_path(const char *prefix, int major, int minor)
430 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
432 if (!dm_task_set_minor(dmt, minor) ||
433 !dm_task_set_major(dmt, major) ||
434 !dm_task_no_flush(dmt) ||
436 !(name = dm_task_get_name(dmt))) {
437 dm_task_destroy(dmt);
441 if (snprintf(path, sizeof(path), "%s%s", prefix ?: "", name) < 0)
444 dm_task_destroy(dmt);
449 char *dm_device_name(const char *path)
453 if (stat(path, &st) < 0 || !S_ISBLK(st.st_mode))
456 return dm_device_path(NULL, major(st.st_rdev), minor(st.st_rdev));
459 static void hex_key(char *hexkey, size_t key_size, const char *key)
463 for(i = 0; i < key_size; i++)
464 sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
467 static size_t int_log10(uint64_t x)
470 for (x /= 10; x > 0; x /= 10)
475 #define CLEN 64 /* 2*MAX_CIPHER_LEN */
476 #define CLENS "63" /* for sscanf length + '\0' */
477 #define CAPIL 144 /* should be enough to fit whole capi string */
478 #define CAPIS "143" /* for sscanf of crypto API string + 16 + \0 */
480 static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size,
481 char *c_dm, int c_dm_size,
482 char *i_dm, int i_dm_size)
484 int c_size = 0, i_size = 0, i;
485 char cipher[CLEN], mode[CLEN], iv[CLEN+1], tmp[CLEN];
488 if (!c_dm || !c_dm_size || !i_dm || !i_dm_size)
491 i = sscanf(org_c, "%" CLENS "[^-]-%" CLENS "s", cipher, tmp);
495 i = sscanf(tmp, "%" CLENS "[^-]-%" CLENS "s", mode, iv);
497 memset(iv, 0, sizeof(iv));
498 strncpy(iv, mode, sizeof(iv)-1);
500 if (snprintf(capi, sizeof(capi), "%s", cipher) < 0)
503 if (snprintf(capi, sizeof(capi), "%s(%s)", mode, cipher) < 0)
509 /* legacy mode: CIPHER-MODE-IV*/
510 i_size = snprintf(i_dm, i_dm_size, "%s", "");
511 c_size = snprintf(c_dm, c_dm_size, "%s", org_c);
512 } else if (!strcmp(org_i, "none")) {
513 /* IV only: capi:MODE(CIPHER)-IV */
514 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:none", tag_size);
515 c_size = snprintf(c_dm, c_dm_size, "capi:%s-%s", capi, iv);
516 } else if (!strcmp(org_i, "aead") && !strcmp(mode, "ccm")) {
517 /* CCM AEAD: capi:rfc4309(MODE(CIPHER))-IV */
518 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
519 c_size = snprintf(c_dm, c_dm_size, "capi:rfc4309(%s)-%s", capi, iv);
520 } else if (!strcmp(org_i, "aead")) {
521 /* AEAD: capi:MODE(CIPHER))-IV */
522 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
523 c_size = snprintf(c_dm, c_dm_size, "capi:%s-%s", capi, iv);
524 } else if (!strcmp(org_i, "poly1305")) {
525 /* POLY1305 AEAD: capi:rfc7539(MODE(CIPHER),POLY1305)-IV */
526 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
527 c_size = snprintf(c_dm, c_dm_size, "capi:rfc7539(%s,poly1305)-%s", capi, iv);
529 /* other AEAD: capi:authenc(<AUTH>,MODE(CIPHER))-IV */
530 i_size = snprintf(i_dm, i_dm_size, " integrity:%u:aead", tag_size);
531 c_size = snprintf(c_dm, c_dm_size, "capi:authenc(%s,%s)-%s", org_i, capi, iv);
534 if (c_size < 0 || c_size == c_dm_size)
536 if (i_size < 0 || i_size == i_dm_size)
542 static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char *i_dm)
544 char cipher[CLEN], mode[CLEN], iv[CLEN], auth[CLEN];
545 char tmp[CAPIL], dmcrypt_tmp[CAPIL*2], capi[CAPIL+1];
553 if (strncmp(c_dm, "capi:", 4)) {
554 if (!(*org_c = strdup(c_dm)))
560 /* modes with capi: prefix */
561 i = sscanf(c_dm, "capi:%" CAPIS "[^-]-%" CLENS "s", tmp, iv);
569 if (tmp[len-1] == ')')
572 if (sscanf(tmp, "rfc4309(%" CAPIS "s", capi) == 1) {
573 if (!(*org_i = strdup("aead")))
575 } else if (sscanf(tmp, "rfc7539(%" CAPIS "[^,],%" CLENS "s", capi, auth) == 2) {
576 if (!(*org_i = strdup(auth)))
578 } else if (sscanf(tmp, "authenc(%" CLENS "[^,],%" CAPIS "s", auth, capi) == 2) {
579 if (!(*org_i = strdup(auth)))
583 if (!(*org_i = strdup(i_dm)))
587 memset(capi, 0, sizeof(capi));
588 strncpy(capi, tmp, sizeof(capi)-1);
591 i = sscanf(capi, "%" CLENS "[^(](%" CLENS "[^)])", mode, cipher);
593 i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv);
595 i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv);
596 if (i < 0 || (size_t)i >= sizeof(dmcrypt_tmp)) {
602 if (!(*org_c = strdup(dmcrypt_tmp))) {
611 static char *_uf(char *buf, size_t buf_size, const char *s, unsigned u)
613 size_t r = snprintf(buf, buf_size, " %s:%u", s, u);
614 assert(r > 0 && r < buf_size);
618 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt */
619 static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags)
621 int r, max_size, null_cipher = 0, num_options = 0, keystr_len = 0;
622 char *params = NULL, *hexkey = NULL;
623 char sector_feature[32], features[512], integrity_dm[256], cipher_dm[256];
628 r = cipher_c2dm(tgt->u.crypt.cipher, tgt->u.crypt.integrity, tgt->u.crypt.tag_size,
629 cipher_dm, sizeof(cipher_dm), integrity_dm, sizeof(integrity_dm));
633 if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
635 if (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT)
637 if (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
639 if (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE)
641 if (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)
643 if (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS)
645 if (tgt->u.crypt.integrity)
647 if (tgt->u.crypt.sector_size != SECTOR_SIZE)
650 if (num_options) { /* MAX length int32 + 15 + 15 + 23 + 18 + 19 + 17 + 13 + int32 + integrity_str */
651 r = snprintf(features, sizeof(features), " %d%s%s%s%s%s%s%s%s", num_options,
652 (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "",
653 (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "",
654 (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "",
655 (flags & CRYPT_ACTIVATE_NO_READ_WORKQUEUE) ? " no_read_workqueue" : "",
656 (flags & CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) ? " no_write_workqueue" : "",
657 (flags & CRYPT_ACTIVATE_IV_LARGE_SECTORS) ? " iv_large_sectors" : "",
658 (tgt->u.crypt.sector_size != SECTOR_SIZE) ?
659 _uf(sector_feature, sizeof(sector_feature), "sector_size", tgt->u.crypt.sector_size) : "",
661 if (r < 0 || (size_t)r >= sizeof(features))
666 if (crypt_is_cipher_null(cipher_dm))
670 hexkey = crypt_safe_alloc(2);
671 else if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
672 keystr_len = strlen(tgt->u.crypt.vk->key_description) + int_log10(tgt->u.crypt.vk->keylength) + 10;
673 hexkey = crypt_safe_alloc(keystr_len);
675 hexkey = crypt_safe_alloc(tgt->u.crypt.vk->keylength * 2 + 1);
681 strncpy(hexkey, "-", 2);
682 else if (flags & CRYPT_ACTIVATE_KEYRING_KEY) {
683 r = snprintf(hexkey, keystr_len, ":%zu:logon:%s", tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key_description);
684 if (r < 0 || r >= keystr_len)
687 hex_key(hexkey, tgt->u.crypt.vk->keylength, tgt->u.crypt.vk->key);
689 max_size = strlen(hexkey) + strlen(cipher_dm) +
690 strlen(device_block_path(tgt->data_device)) +
691 strlen(features) + 64;
692 params = crypt_safe_alloc(max_size);
696 r = snprintf(params, max_size, "%s %s %" PRIu64 " %s %" PRIu64 "%s",
697 cipher_dm, hexkey, tgt->u.crypt.iv_offset,
698 device_block_path(tgt->data_device), tgt->u.crypt.offset,
700 if (r < 0 || r >= max_size) {
701 crypt_safe_free(params);
705 crypt_safe_free(hexkey);
709 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity */
710 static char *get_dm_verity_params(const struct dm_target *tgt, uint32_t flags)
712 int max_size, max_fec_size, max_verify_size, r, num_options = 0;
713 struct crypt_params_verity *vp;
714 char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
715 char features[256], *fec_features = NULL, *verity_verify_args = NULL;
717 if (!tgt || !tgt->u.verity.vp)
720 vp = tgt->u.verity.vp;
722 /* These flags are not compatible */
723 if ((flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) &&
724 (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION))
725 flags &= ~CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
726 if ((flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) &&
727 (flags & (CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)))
728 flags &= ~CRYPT_ACTIVATE_IGNORE_CORRUPTION;
730 if (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION)
732 if (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION)
734 if (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION)
736 if (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS)
738 if (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE)
741 max_fec_size = (tgt->u.verity.fec_device ? strlen(device_block_path(tgt->u.verity.fec_device)) : 0) + 256;
742 fec_features = crypt_safe_alloc(max_fec_size);
746 if (tgt->u.verity.fec_device) { /* MAX length 21 + path + 11 + int64 + 12 + int64 + 11 + int32 */
748 r = snprintf(fec_features, max_fec_size,
749 " use_fec_from_device %s fec_start %" PRIu64 " fec_blocks %" PRIu64 " fec_roots %" PRIu32,
750 device_block_path(tgt->u.verity.fec_device), tgt->u.verity.fec_offset,
751 tgt->u.verity.fec_blocks, vp->fec_roots);
752 if (r < 0 || r >= max_fec_size)
755 *fec_features = '\0';
757 max_verify_size = (tgt->u.verity.root_hash_sig_key_desc ? strlen(tgt->u.verity.root_hash_sig_key_desc) : 0) + 32;
758 verity_verify_args = crypt_safe_alloc(max_verify_size);
759 if (!verity_verify_args)
761 if (tgt->u.verity.root_hash_sig_key_desc) { /* MAX length 24 + key_str */
763 r = snprintf(verity_verify_args, max_verify_size,
764 " root_hash_sig_key_desc %s", tgt->u.verity.root_hash_sig_key_desc);
765 if (r < 0 || r >= max_verify_size)
768 *verity_verify_args = '\0';
770 if (num_options) { /* MAX length int32 + 18 + 22 + 20 + 19 + 19 */
771 r = snprintf(features, sizeof(features), " %d%s%s%s%s%s", num_options,
772 (flags & CRYPT_ACTIVATE_IGNORE_CORRUPTION) ? " ignore_corruption" : "",
773 (flags & CRYPT_ACTIVATE_RESTART_ON_CORRUPTION) ? " restart_on_corruption" : "",
774 (flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION) ? " panic_on_corruption" : "",
775 (flags & CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS) ? " ignore_zero_blocks" : "",
776 (flags & CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) ? " check_at_most_once" : "");
777 if (r < 0 || (size_t)r >= sizeof(features))
782 hexroot = crypt_safe_alloc(tgt->u.verity.root_hash_size * 2 + 1);
785 hex_key(hexroot, tgt->u.verity.root_hash_size, tgt->u.verity.root_hash);
787 hexsalt = crypt_safe_alloc(vp->salt_size ? vp->salt_size * 2 + 1 : 2);
791 hex_key(hexsalt, vp->salt_size, vp->salt);
793 strncpy(hexsalt, "-", 2);
795 max_size = strlen(hexroot) + strlen(hexsalt) +
796 strlen(device_block_path(tgt->data_device)) +
797 strlen(device_block_path(tgt->u.verity.hash_device)) +
798 strlen(vp->hash_name) + strlen(features) + strlen(fec_features) + 128 +
799 strlen(verity_verify_args);
801 params = crypt_safe_alloc(max_size);
805 r = snprintf(params, max_size,
806 "%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s%s%s%s",
807 vp->hash_type, device_block_path(tgt->data_device),
808 device_block_path(tgt->u.verity.hash_device),
809 vp->data_block_size, vp->hash_block_size,
810 vp->data_size, tgt->u.verity.hash_offset,
811 vp->hash_name, hexroot, hexsalt, features, fec_features,
813 if (r < 0 || r >= max_size) {
814 crypt_safe_free(params);
818 crypt_safe_free(fec_features);
819 crypt_safe_free(verity_verify_args);
820 crypt_safe_free(hexroot);
821 crypt_safe_free(hexsalt);
825 static char *get_dm_integrity_params(const struct dm_target *tgt, uint32_t flags)
827 int r, max_size, max_integrity, max_journal_integrity, max_journal_crypt, num_options = 0;
828 char *params_out = NULL, *params, *hexkey, mode, feature[6][32];
829 char *features, *integrity, *journal_integrity, *journal_crypt;
834 max_integrity = (tgt->u.integrity.integrity && tgt->u.integrity.vk ? tgt->u.integrity.vk->keylength * 2 : 0) +
835 (tgt->u.integrity.integrity ? strlen(tgt->u.integrity.integrity) : 0) + 32;
836 max_journal_integrity = (tgt->u.integrity.journal_integrity && tgt->u.integrity.journal_integrity_key ?
837 tgt->u.integrity.journal_integrity_key->keylength * 2 : 0) +
838 (tgt->u.integrity.journal_integrity ? strlen(tgt->u.integrity.journal_integrity) : 0) + 32;
839 max_journal_crypt = (tgt->u.integrity.journal_crypt && tgt->u.integrity.journal_crypt_key ?
840 tgt->u.integrity.journal_crypt_key->keylength * 2 : 0) +
841 (tgt->u.integrity.journal_crypt ? strlen(tgt->u.integrity.journal_crypt) : 0) + 32;
842 max_size = strlen(device_block_path(tgt->data_device)) +
843 (tgt->u.integrity.meta_device ? strlen(device_block_path(tgt->u.integrity.meta_device)) : 0) +
844 max_integrity + max_journal_integrity + max_journal_crypt + 512;
846 params = crypt_safe_alloc(max_size);
847 features = crypt_safe_alloc(max_size);
848 integrity = crypt_safe_alloc(max_integrity);
849 journal_integrity = crypt_safe_alloc(max_journal_integrity);
850 journal_crypt = crypt_safe_alloc(max_journal_crypt);
851 if (!params || !features || !integrity || !journal_integrity || !journal_crypt)
854 if (tgt->u.integrity.integrity) { /* MAX length 16 + str_integrity + str_key */
857 if (tgt->u.integrity.vk) {
858 hexkey = crypt_safe_alloc(tgt->u.integrity.vk->keylength * 2 + 1);
861 hex_key(hexkey, tgt->u.integrity.vk->keylength, tgt->u.integrity.vk->key);
865 r = snprintf(integrity, max_integrity, " internal_hash:%s%s%s",
866 tgt->u.integrity.integrity, hexkey ? ":" : "", hexkey ?: "");
867 crypt_safe_free(hexkey);
868 if (r < 0 || r >= max_integrity)
872 if (tgt->u.integrity.journal_integrity) { /* MAX length 14 + str_journal_integrity + str_key */
875 if (tgt->u.integrity.journal_integrity_key) {
876 hexkey = crypt_safe_alloc(tgt->u.integrity.journal_integrity_key->keylength * 2 + 1);
879 hex_key(hexkey, tgt->u.integrity.journal_integrity_key->keylength,
880 tgt->u.integrity.journal_integrity_key->key);
884 r = snprintf(journal_integrity, max_journal_integrity, " journal_mac:%s%s%s",
885 tgt->u.integrity.journal_integrity, hexkey ? ":" : "", hexkey ?: "");
886 crypt_safe_free(hexkey);
887 if (r < 0 || r >= max_journal_integrity)
891 if (tgt->u.integrity.journal_crypt) { /* MAX length 15 + str_journal_crypt + str_key */
894 if (tgt->u.integrity.journal_crypt_key) {
895 hexkey = crypt_safe_alloc(tgt->u.integrity.journal_crypt_key->keylength * 2 + 1);
898 hex_key(hexkey, tgt->u.integrity.journal_crypt_key->keylength,
899 tgt->u.integrity.journal_crypt_key->key);
903 r = snprintf(journal_crypt, max_journal_crypt, " journal_crypt:%s%s%s",
904 tgt->u.integrity.journal_crypt, hexkey ? ":" : "", hexkey ?: "");
905 crypt_safe_free(hexkey);
906 if (r < 0 || r >= max_journal_crypt)
910 if (tgt->u.integrity.journal_size)
912 if (tgt->u.integrity.journal_watermark)
914 if (tgt->u.integrity.journal_commit_time)
916 if (tgt->u.integrity.interleave_sectors)
918 if (tgt->u.integrity.sector_size)
920 if (tgt->u.integrity.buffer_sectors)
922 if (tgt->u.integrity.fix_padding)
924 if (tgt->u.integrity.fix_hmac)
926 if (tgt->u.integrity.legacy_recalc)
928 if (tgt->u.integrity.meta_device)
930 if (flags & CRYPT_ACTIVATE_RECALCULATE)
932 if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
935 r = snprintf(features, max_size, "%d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", num_options,
936 tgt->u.integrity.journal_size ? _uf(feature[0], sizeof(feature[0]), /* MAX length 17 + int32 */
937 "journal_sectors", (unsigned)(tgt->u.integrity.journal_size / SECTOR_SIZE)) : "",
938 tgt->u.integrity.journal_watermark ? _uf(feature[1], sizeof(feature[1]), /* MAX length 19 + int32 */
939 /* bitmap overloaded values */
940 (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) ? "sectors_per_bit" : "journal_watermark",
941 tgt->u.integrity.journal_watermark) : "",
942 tgt->u.integrity.journal_commit_time ? _uf(feature[2], sizeof(feature[2]), /* MAX length 23 + int32 */
943 /* bitmap overloaded values */
944 (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) ? "bitmap_flush_interval" : "commit_time",
945 tgt->u.integrity.journal_commit_time) : "",
946 tgt->u.integrity.interleave_sectors ? _uf(feature[3], sizeof(feature[3]), /* MAX length 20 + int32 */
947 "interleave_sectors", tgt->u.integrity.interleave_sectors) : "",
948 tgt->u.integrity.sector_size ? _uf(feature[4], sizeof(feature[4]), /* MAX length 12 + int32 */
949 "block_size", tgt->u.integrity.sector_size) : "",
950 tgt->u.integrity.buffer_sectors ? _uf(feature[5], sizeof(feature[5]), /* MAX length 16 + int32 */
951 "buffer_sectors", tgt->u.integrity.buffer_sectors) : "",
952 tgt->u.integrity.integrity ? integrity : "",
953 tgt->u.integrity.journal_integrity ? journal_integrity : "",
954 tgt->u.integrity.journal_crypt ? journal_crypt : "",
955 tgt->u.integrity.fix_padding ? " fix_padding" : "", /* MAX length 12 */
956 tgt->u.integrity.fix_hmac ? " fix_hmac" : "", /* MAX length 9 */
957 tgt->u.integrity.legacy_recalc ? " legacy_recalculate" : "", /* MAX length 19 */
958 flags & CRYPT_ACTIVATE_RECALCULATE ? " recalculate" : "", /* MAX length 12 */
959 flags & CRYPT_ACTIVATE_ALLOW_DISCARDS ? " allow_discards" : "", /* MAX length 15 */
960 tgt->u.integrity.meta_device ? " meta_device:" : "", /* MAX length 13 + str_device */
961 tgt->u.integrity.meta_device ? device_block_path(tgt->u.integrity.meta_device) : "");
962 if (r < 0 || r >= max_size)
965 if (flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP)
967 else if (flags & CRYPT_ACTIVATE_RECOVERY)
969 else if (flags & CRYPT_ACTIVATE_NO_JOURNAL)
974 r = snprintf(params, max_size, "%s %" PRIu64 " %d %c %s",
975 device_block_path(tgt->data_device), tgt->u.integrity.offset,
976 tgt->u.integrity.tag_size, mode, features);
977 if (r < 0 || r >= max_size)
982 crypt_safe_free(features);
983 crypt_safe_free(integrity);
984 crypt_safe_free(journal_integrity);
985 crypt_safe_free(journal_crypt);
987 crypt_safe_free(params);
992 static char *get_dm_linear_params(const struct dm_target *tgt, uint32_t flags)
996 int max_size = strlen(device_block_path(tgt->data_device)) + int_log10(tgt->u.linear.offset) + 3;
998 params = crypt_safe_alloc(max_size);
1002 r = snprintf(params, max_size, "%s %" PRIu64,
1003 device_block_path(tgt->data_device), tgt->u.linear.offset);
1005 if (r < 0 || r >= max_size) {
1006 crypt_safe_free(params);
1013 static char *get_dm_zero_params(const struct dm_target *tgt, uint32_t flags)
1015 char *params = crypt_safe_alloc(1);
1024 static int _dm_remove(const char *name, int udev_wait, int deferred)
1027 struct dm_task *dmt;
1028 uint32_t cookie = 0;
1030 if (!_dm_use_udev())
1033 if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
1036 if (!dm_task_set_name(dmt, name))
1039 #if HAVE_DECL_DM_TASK_RETRY_REMOVE
1040 if (!dm_task_retry_remove(dmt))
1043 #if HAVE_DECL_DM_TASK_DEFERRED_REMOVE
1044 if (deferred && !dm_task_deferred_remove(dmt))
1047 if (udev_wait && !_dm_task_set_cookie(dmt, &cookie, DM_UDEV_DISABLE_LIBRARY_FALLBACK))
1050 r = dm_task_run(dmt);
1053 (void)_dm_udev_wait(cookie);
1055 dm_task_destroy(dmt);
1059 static int _dm_simple(int task, const char *name, uint32_t dmflags)
1062 struct dm_task *dmt;
1064 if (!(dmt = dm_task_create(task)))
1067 if (name && !dm_task_set_name(dmt, name))
1070 if (task == DM_DEVICE_SUSPEND &&
1071 (dmflags & DM_SUSPEND_SKIP_LOCKFS) && !dm_task_skip_lockfs(dmt))
1074 if (task == DM_DEVICE_SUSPEND &&
1075 (dmflags & DM_SUSPEND_NOFLUSH) && !dm_task_no_flush(dmt))
1078 r = dm_task_run(dmt);
1080 dm_task_destroy(dmt);
1084 static int _dm_resume_device(const char *name, uint32_t flags);
1086 static int _error_device(const char *name, size_t size)
1088 struct dm_task *dmt;
1091 if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
1094 if (!dm_task_set_name(dmt, name))
1097 if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", ""))
1100 if (!dm_task_set_ro(dmt))
1103 if (!dm_task_no_open_count(dmt))
1106 if (!dm_task_run(dmt))
1109 if (_dm_resume_device(name, 0)) {
1110 _dm_simple(DM_DEVICE_CLEAR, name, 0);
1117 dm_task_destroy(dmt);
1121 int dm_error_device(struct crypt_device *cd, const char *name)
1124 struct crypt_dm_active_device dmd;
1129 if (dm_init_context(cd, DM_UNKNOWN))
1132 if ((dm_query_device(cd, name, 0, &dmd) >= 0) && _error_device(name, dmd.size))
1137 dm_targets_free(cd, &dmd);
1144 int dm_clear_device(struct crypt_device *cd, const char *name)
1151 if (dm_init_context(cd, DM_UNKNOWN))
1154 if (_dm_simple(DM_DEVICE_CLEAR, name, 0))
1164 int dm_remove_device(struct crypt_device *cd, const char *name, uint32_t flags)
1166 struct crypt_dm_active_device dmd = {};
1168 int retries = (flags & CRYPT_DEACTIVATE_FORCE) ? RETRY_COUNT : 1;
1169 int deferred = (flags & CRYPT_DEACTIVATE_DEFERRED) ? 1 : 0;
1170 int error_target = 0;
1176 if (dm_init_context(cd, DM_UNKNOWN))
1179 if (deferred && !dm_flags(cd, DM_UNKNOWN, &dmt_flags) && !(dmt_flags & DM_DEFERRED_SUPPORTED)) {
1180 log_err(cd, _("Requested deferred flag is not supported."));
1186 r = _dm_remove(name, 1, deferred) ? 0 : -EINVAL;
1187 if (--retries && r) {
1188 log_dbg(cd, "WARNING: other process locked internal device %s, %s.",
1189 name, retries ? "retrying remove" : "giving up");
1191 if ((flags & CRYPT_DEACTIVATE_FORCE) && !error_target) {
1192 /* If force flag is set, replace device with error, read-only target.
1193 * it should stop processes from reading it and also removed underlying
1194 * device from mapping, so it is usable again.
1195 * Anyway, if some process try to read temporary cryptsetup device,
1196 * it is bug - no other process should try touch it (e.g. udev).
1198 if (!dm_query_device(cd, name, 0, &dmd)) {
1199 _error_device(name, dmd.size);
1204 } while (r == -EINVAL && retries);
1206 dm_task_update_nodes();
1212 #define UUID_LEN 37 /* 36 + \0, libuuid ... */
1214 * UUID has format: CRYPT-<devicetype>-[<uuid>-]<device name>
1216 * CRYPT-LUKS1-00000000000000000000000000000000-name
1219 static int dm_prepare_uuid(struct crypt_device *cd, const char *name, const char *type,
1220 const char *uuid, char *buf, size_t buflen)
1222 char *ptr, uuid2[UUID_LEN] = {0};
1226 /* Remove '-' chars */
1228 if (uuid_parse(uuid, uu) < 0) {
1229 log_dbg(cd, "Requested UUID %s has invalid format.", uuid);
1233 for (ptr = uuid2, i = 0; i < UUID_LEN; i++)
1234 if (uuid[i] != '-') {
1240 i = snprintf(buf, buflen, DM_UUID_PREFIX "%s%s%s%s%s",
1241 type ?: "", type ? "-" : "",
1242 uuid2[0] ? uuid2 : "", uuid2[0] ? "-" : "",
1247 log_dbg(cd, "DM-UUID is %s", buf);
1248 if ((size_t)i >= buflen)
1249 log_err(cd, _("DM-UUID for device %s was truncated."), name);
1254 int lookup_dm_dev_by_uuid(struct crypt_device *cd, const char *uuid, const char *type)
1258 char dev_uuid[DM_UUID_LEN + DM_BY_ID_PREFIX_LEN] = DM_BY_ID_PREFIX;
1260 if (!dm_prepare_uuid(cd, "", type, uuid, dev_uuid + DM_BY_ID_PREFIX_LEN, DM_UUID_LEN))
1263 c = strrchr(dev_uuid, '-');
1267 /* cut of dm name */
1270 r = lookup_by_disk_id(dev_uuid);
1272 log_dbg(cd, "Search by disk id not available. Using sysfs instead.");
1273 r = lookup_by_sysfs_uuid_field(dev_uuid + DM_BY_ID_PREFIX_LEN, DM_UUID_LEN);
1279 static int _add_dm_targets(struct dm_task *dmt, struct crypt_dm_active_device *dmd)
1282 struct dm_target *tgt = &dmd->segment;
1285 switch (tgt->type) {
1287 target = DM_CRYPT_TARGET;
1290 target = DM_VERITY_TARGET;
1293 target = DM_INTEGRITY_TARGET;
1296 target = DM_LINEAR_TARGET;
1299 target = DM_ZERO_TARGET;
1305 if (!dm_task_add_target(dmt, tgt->offset, tgt->size, target, tgt->params))
1314 static void _destroy_dm_targets_params(struct crypt_dm_active_device *dmd)
1316 struct dm_target *t = &dmd->segment;
1319 crypt_safe_free(t->params);
1325 static int _create_dm_targets_params(struct crypt_dm_active_device *dmd)
1328 struct dm_target *tgt = &dmd->segment;
1331 if (tgt->type == DM_CRYPT)
1332 tgt->params = get_dm_crypt_params(tgt, dmd->flags);
1333 else if (tgt->type == DM_VERITY)
1334 tgt->params = get_dm_verity_params(tgt, dmd->flags);
1335 else if (tgt->type == DM_INTEGRITY)
1336 tgt->params = get_dm_integrity_params(tgt, dmd->flags);
1337 else if (tgt->type == DM_LINEAR)
1338 tgt->params = get_dm_linear_params(tgt, dmd->flags);
1339 else if (tgt->type == DM_ZERO)
1340 tgt->params = get_dm_zero_params(tgt, dmd->flags);
1355 _destroy_dm_targets_params(dmd);
1359 static bool dm_device_exists(struct crypt_device *cd, const char *name)
1361 int r = dm_status_device(cd, name);
1362 return (r >= 0 || r == -EEXIST);
1365 static int _dm_create_device(struct crypt_device *cd, const char *name, const char *type,
1366 const char *uuid, struct crypt_dm_active_device *dmd)
1368 struct dm_task *dmt = NULL;
1370 char dev_uuid[DM_UUID_LEN] = {0};
1372 uint32_t cookie = 0, read_ahead = 0;
1373 uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
1375 if (dmd->flags & CRYPT_ACTIVATE_PRIVATE)
1376 udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
1378 /* All devices must have DM_UUID, only resize on old device is exception */
1379 if (!dm_prepare_uuid(cd, name, type, dmd->uuid, dev_uuid, sizeof(dev_uuid)))
1382 if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
1385 if (!dm_task_set_name(dmt, name))
1388 if (!dm_task_set_uuid(dmt, dev_uuid))
1391 if (!dm_task_secure_data(dmt))
1393 if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
1396 r = _create_dm_targets_params(dmd);
1400 r = _add_dm_targets(dmt, dmd);
1406 #ifdef DM_READ_AHEAD_MINIMUM_FLAG
1407 if (device_read_ahead(dmd->segment.data_device, &read_ahead) &&
1408 !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
1411 if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
1414 if (!dm_task_run(dmt)) {
1415 if (dm_device_exists(cd, name))
1420 if (dm_task_get_info(dmt, &dmi))
1423 if (_dm_use_udev()) {
1424 (void)_dm_udev_wait(cookie);
1429 _dm_remove(name, 1, 0);
1432 if (cookie && _dm_use_udev())
1433 (void)_dm_udev_wait(cookie);
1436 dm_task_destroy(dmt);
1438 dm_task_update_nodes();
1440 /* If code just loaded target module, update versions */
1441 _dm_check_versions(cd, dmd->segment.type);
1443 _destroy_dm_targets_params(dmd);
1448 static int _dm_resume_device(const char *name, uint32_t dmflags)
1450 struct dm_task *dmt;
1452 uint32_t cookie = 0;
1453 uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK;
1455 if (dmflags & DM_RESUME_PRIVATE)
1456 udev_flags |= CRYPT_TEMP_UDEV_FLAGS;
1458 if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
1461 if (!dm_task_set_name(dmt, name))
1464 if ((dmflags & DM_SUSPEND_SKIP_LOCKFS) && !dm_task_skip_lockfs(dmt))
1467 if ((dmflags & DM_SUSPEND_NOFLUSH) && !dm_task_no_flush(dmt))
1470 if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
1473 if (dm_task_run(dmt))
1476 if (cookie && _dm_use_udev())
1477 (void)_dm_udev_wait(cookie);
1479 dm_task_destroy(dmt);
1481 dm_task_update_nodes();
1486 static int _dm_reload_device(struct crypt_device *cd, const char *name,
1487 struct crypt_dm_active_device *dmd)
1490 struct dm_task *dmt = NULL;
1491 uint32_t read_ahead = 0;
1493 /* All devices must have DM_UUID, only resize on old device is exception */
1494 if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
1497 if (!dm_task_set_name(dmt, name))
1500 if (!dm_task_secure_data(dmt))
1502 if ((dmd->flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
1505 r = _create_dm_targets_params(dmd);
1509 r = _add_dm_targets(dmt, dmd);
1515 #ifdef DM_READ_AHEAD_MINIMUM_FLAG
1516 if (device_read_ahead(dmd->segment.data_device, &read_ahead) &&
1517 !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
1521 if (dm_task_run(dmt))
1525 dm_task_destroy(dmt);
1527 /* If code just loaded target module, update versions */
1528 _dm_check_versions(cd, dmd->segment.type);
1530 _destroy_dm_targets_params(dmd);
1535 static void crypt_free_verity_params(struct crypt_params_verity *vp)
1540 free(CONST_CAST(void*)vp->hash_name);
1541 free(CONST_CAST(void*)vp->data_device);
1542 free(CONST_CAST(void*)vp->hash_device);
1543 free(CONST_CAST(void*)vp->fec_device);
1544 free(CONST_CAST(void*)vp->salt);
1548 static void _dm_target_free_query_path(struct crypt_device *cd, struct dm_target *tgt)
1552 crypt_free_volume_key(tgt->u.crypt.vk);
1553 free(CONST_CAST(void*)tgt->u.crypt.cipher);
1556 free(CONST_CAST(void*)tgt->u.integrity.integrity);
1557 crypt_free_volume_key(tgt->u.integrity.vk);
1559 free(CONST_CAST(void*)tgt->u.integrity.journal_integrity);
1560 crypt_free_volume_key(tgt->u.integrity.journal_integrity_key);
1562 free(CONST_CAST(void*)tgt->u.integrity.journal_crypt);
1563 crypt_free_volume_key(tgt->u.integrity.journal_crypt_key);
1565 device_free(cd, tgt->u.integrity.meta_device);
1568 crypt_free_verity_params(tgt->u.verity.vp);
1569 device_free(cd, tgt->u.verity.hash_device);
1570 free(CONST_CAST(void*)tgt->u.verity.root_hash);
1571 free(CONST_CAST(void*)tgt->u.verity.root_hash_sig_key_desc);
1580 log_err(cd, _("Unknown dm target type."));
1584 device_free(cd, tgt->data_device);
1587 static void _dm_target_erase(struct crypt_device *cd, struct dm_target *tgt)
1589 if (tgt->direction == TARGET_QUERY)
1590 _dm_target_free_query_path(cd, tgt);
1592 if (tgt->type == DM_CRYPT)
1593 free(CONST_CAST(void*)tgt->u.crypt.integrity);
1596 void dm_targets_free(struct crypt_device *cd, struct crypt_dm_active_device *dmd)
1598 struct dm_target *t = &dmd->segment, *next = t->next;
1600 _dm_target_erase(cd, t);
1605 _dm_target_erase(cd, t);
1609 memset(&dmd->segment, 0, sizeof(dmd->segment));
1612 int dm_targets_allocate(struct dm_target *first, unsigned count)
1614 if (!first || first->next || !count)
1618 first->next = crypt_zalloc(sizeof(*first));
1621 first = first->next;
1627 static int check_retry(struct crypt_device *cd, uint32_t *dmd_flags, uint32_t dmt_flags)
1631 /* If discard not supported try to load without discard */
1632 if ((*dmd_flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
1633 !(dmt_flags & DM_DISCARDS_SUPPORTED)) {
1634 log_dbg(cd, "Discard/TRIM is not supported");
1635 *dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_ALLOW_DISCARDS;
1639 /* If kernel keyring is not supported load key directly in dm-crypt */
1640 if ((*dmd_flags & CRYPT_ACTIVATE_KEYRING_KEY) &&
1641 !(dmt_flags & DM_KERNEL_KEYRING_SUPPORTED)) {
1642 log_dbg(cd, "dm-crypt does not support kernel keyring");
1643 *dmd_flags = *dmd_flags & ~CRYPT_ACTIVATE_KEYRING_KEY;
1647 /* Drop performance options if not supported */
1648 if ((*dmd_flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
1649 !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED))) {
1650 log_dbg(cd, "dm-crypt does not support performance options");
1651 *dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_SAME_CPU_CRYPT | CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS);
1655 /* Drop no workqueue options if not supported */
1656 if ((*dmd_flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
1657 !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED)) {
1658 log_dbg(cd, "dm-crypt does not support performance options");
1659 *dmd_flags = *dmd_flags & ~(CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE);
1666 int dm_create_device(struct crypt_device *cd, const char *name,
1668 struct crypt_dm_active_device *dmd)
1670 uint32_t dmt_flags = 0;
1676 if (dm_init_context(cd, dmd->segment.type))
1679 r = _dm_create_device(cd, name, type, dmd->uuid, dmd);
1681 if (r < 0 && dm_flags(cd, dmd->segment.type, &dmt_flags))
1684 if (r && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR || dmd->segment.type == DM_ZERO) &&
1685 check_retry(cd, &dmd->flags, dmt_flags)) {
1686 log_dbg(cd, "Retrying open without incompatible options.");
1687 r = _dm_create_device(cd, name, type, dmd->uuid, dmd);
1691 * Print warning if activating dm-crypt cipher_null device unless it's reencryption helper or
1692 * keyslot encryption helper device (LUKS1 cipher_null devices).
1694 if (!r && !(dmd->flags & CRYPT_ACTIVATE_PRIVATE) && single_segment(dmd) && dmd->segment.type == DM_CRYPT &&
1695 crypt_is_cipher_null(dmd->segment.u.crypt.cipher))
1696 log_dbg(cd, "Activated dm-crypt device with cipher_null. Device is not encrypted.");
1699 dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) &&
1700 !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
1701 log_err(cd, _("Requested dm-crypt performance options are not supported."));
1704 dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE) &&
1705 !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
1706 log_err(cd, _("Requested dm-crypt performance options are not supported."));
1708 if (r == -EINVAL && dmd->flags & (CRYPT_ACTIVATE_IGNORE_CORRUPTION|
1709 CRYPT_ACTIVATE_RESTART_ON_CORRUPTION|
1710 CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS|
1711 CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE) &&
1712 !(dmt_flags & DM_VERITY_ON_CORRUPTION_SUPPORTED))
1713 log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
1715 if (r == -EINVAL && dmd->flags & CRYPT_ACTIVATE_PANIC_ON_CORRUPTION &&
1716 !(dmt_flags & DM_VERITY_PANIC_CORRUPTION_SUPPORTED))
1717 log_err(cd, _("Requested dm-verity data corruption handling options are not supported."));
1719 if (r == -EINVAL && dmd->segment.type == DM_VERITY &&
1720 dmd->segment.u.verity.fec_device && !(dmt_flags & DM_VERITY_FEC_SUPPORTED))
1721 log_err(cd, _("Requested dm-verity FEC options are not supported."));
1723 if (r == -EINVAL && dmd->segment.type == DM_CRYPT) {
1724 if (dmd->segment.u.crypt.integrity && !(dmt_flags & DM_INTEGRITY_SUPPORTED))
1725 log_err(cd, _("Requested data integrity options are not supported."));
1726 if (dmd->segment.u.crypt.sector_size != SECTOR_SIZE && !(dmt_flags & DM_SECTOR_SIZE_SUPPORTED))
1727 log_err(cd, _("Requested sector_size option is not supported."));
1730 if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_RECALCULATE) &&
1731 !(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
1732 log_err(cd, _("Requested automatic recalculation of integrity tags is not supported."));
1734 if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
1735 !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
1736 log_err(cd, _("Discard/TRIM is not supported."));
1738 if (r == -EINVAL && dmd->segment.type == DM_INTEGRITY && (dmd->flags & CRYPT_ACTIVATE_NO_JOURNAL_BITMAP) &&
1739 !(dmt_flags & DM_INTEGRITY_BITMAP_SUPPORTED))
1740 log_err(cd, _("Requested dm-integrity bitmap mode is not supported."));
1746 int dm_reload_device(struct crypt_device *cd, const char *name,
1747 struct crypt_dm_active_device *dmd, uint32_t dmflags, unsigned resume)
1755 if (dm_init_context(cd, dmd->segment.type))
1758 if (dm_flags(cd, DM_INTEGRITY, &dmt_flags) || !(dmt_flags & DM_INTEGRITY_RECALC_SUPPORTED))
1759 dmd->flags &= ~CRYPT_ACTIVATE_RECALCULATE;
1761 r = _dm_reload_device(cd, name, dmd);
1763 if (r == -EINVAL && (dmd->segment.type == DM_CRYPT || dmd->segment.type == DM_LINEAR)) {
1764 if ((dmd->flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)) &&
1765 !dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & (DM_SAME_CPU_CRYPT_SUPPORTED | DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
1766 log_err(cd, _("Requested dm-crypt performance options are not supported."));
1767 if ((dmd->flags & (CRYPT_ACTIVATE_NO_READ_WORKQUEUE | CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE)) &&
1768 !dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_CRYPT_NO_WORKQUEUE_SUPPORTED))
1769 log_err(cd, _("Requested dm-crypt performance options are not supported."));
1770 if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
1771 !dm_flags(cd, DM_CRYPT, &dmt_flags) && !(dmt_flags & DM_DISCARDS_SUPPORTED))
1772 log_err(cd, _("Discard/TRIM is not supported."));
1773 if ((dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
1774 !dm_flags(cd, DM_INTEGRITY, &dmt_flags) && !(dmt_flags & DM_INTEGRITY_DISCARDS_SUPPORTED))
1775 log_err(cd, _("Discard/TRIM is not supported."));
1779 r = _dm_resume_device(name, dmflags | act2dmflags(dmd->flags));
1785 static int dm_status_dmi(const char *name, struct dm_info *dmi,
1786 const char *target, char **status_line)
1788 struct dm_task *dmt;
1789 uint64_t start, length;
1790 char *target_type, *params = NULL;
1793 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
1796 if (!dm_task_no_flush(dmt))
1799 if (!dm_task_set_name(dmt, name))
1802 if (!dm_task_run(dmt))
1805 if (!dm_task_get_info(dmt, dmi))
1814 dm_get_next_target(dmt, NULL, &start, &length,
1815 &target_type, ¶ms);
1817 if (!target_type || start != 0)
1820 if (target && strcmp(target_type, target))
1823 /* for target == NULL check all supported */
1824 if (!target && (strcmp(target_type, DM_CRYPT_TARGET) &&
1825 strcmp(target_type, DM_VERITY_TARGET) &&
1826 strcmp(target_type, DM_INTEGRITY_TARGET) &&
1827 strcmp(target_type, DM_LINEAR_TARGET) &&
1828 strcmp(target_type, DM_ZERO_TARGET) &&
1829 strcmp(target_type, DM_ERROR_TARGET)))
1833 if (!r && status_line && !(*status_line = strdup(params)))
1837 dm_task_destroy(dmt);
1842 int dm_status_device(struct crypt_device *cd, const char *name)
1848 /* libdevmapper is too clever and handles
1849 * path argument differently with error.
1850 * Fail early here if parameter is non-existent path.
1852 if (strchr(name, '/') && stat(name, &st) < 0)
1855 if (dm_init_context(cd, DM_UNKNOWN))
1857 r = dm_status_dmi(name, &dmi, NULL, NULL);
1863 return (dmi.open_count > 0) ? 1 : 0;
1866 int dm_status_suspended(struct crypt_device *cd, const char *name)
1871 if (dm_init_context(cd, DM_UNKNOWN))
1873 r = dm_status_dmi(name, &dmi, NULL, NULL);
1879 return dmi.suspended ? 1 : 0;
1882 static int _dm_status_verity_ok(struct crypt_device *cd, const char *name)
1886 char *status_line = NULL;
1888 r = dm_status_dmi(name, &dmi, DM_VERITY_TARGET, &status_line);
1889 if (r < 0 || !status_line) {
1894 log_dbg(cd, "Verity volume %s status is %s.", name, status_line ?: "");
1895 r = status_line[0] == 'V' ? 1 : 0;
1901 int dm_status_verity_ok(struct crypt_device *cd, const char *name)
1905 if (dm_init_context(cd, DM_VERITY))
1907 r = _dm_status_verity_ok(cd, name);
1912 int dm_status_integrity_failures(struct crypt_device *cd, const char *name, uint64_t *count)
1916 char *status_line = NULL;
1918 if (dm_init_context(cd, DM_INTEGRITY))
1921 r = dm_status_dmi(name, &dmi, DM_INTEGRITY_TARGET, &status_line);
1922 if (r < 0 || !status_line) {
1928 log_dbg(cd, "Integrity volume %s failure status is %s.", name, status_line ?: "");
1929 *count = strtoull(status_line, NULL, 10);
1936 /* FIXME use hex wrapper, user val wrappers for line parsing */
1937 static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags,
1938 char *params, struct dm_target *tgt,
1939 uint32_t *act_flags)
1942 char *rcipher, *rintegrity, *key_, *rdevice, *endp, buffer[3], *arg, *key_desc;
1943 unsigned int i, val;
1946 struct device *data_device = NULL;
1947 char *cipher = NULL, *integrity = NULL;
1948 struct volume_key *vk = NULL;
1950 tgt->type = DM_CRYPT;
1951 tgt->direction = TARGET_QUERY;
1952 tgt->u.crypt.sector_size = SECTOR_SIZE;
1956 rcipher = strsep(¶ms, " ");
1960 key_ = strsep(¶ms, " ");
1963 val64 = strtoull(params, ¶ms, 10);
1968 tgt->u.crypt.iv_offset = val64;
1971 rdevice = strsep(¶ms, " ");
1972 if (get_flags & DM_ACTIVE_DEVICE) {
1973 arg = crypt_lookup_dev(rdevice);
1974 r = device_alloc(cd, &data_device, arg);
1976 if (r < 0 && r != -ENOTBLK)
1985 val64 = strtoull(params, ¶ms, 10);
1986 tgt->u.crypt.offset = val64;
1988 tgt->u.crypt.tag_size = 0;
1990 /* Features section, available since crypt target version 1.11 */
1996 /* Number of arguments */
1997 val64 = strtoull(params, ¶ms, 10);
2002 for (i = 0; i < val64; i++) {
2005 arg = strsep(¶ms, " ");
2006 if (!strcasecmp(arg, "allow_discards"))
2007 *act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
2008 else if (!strcasecmp(arg, "same_cpu_crypt"))
2009 *act_flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
2010 else if (!strcasecmp(arg, "submit_from_crypt_cpus"))
2011 *act_flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
2012 else if (!strcasecmp(arg, "no_read_workqueue"))
2013 *act_flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
2014 else if (!strcasecmp(arg, "no_write_workqueue"))
2015 *act_flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
2016 else if (!strcasecmp(arg, "iv_large_sectors"))
2017 *act_flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
2018 else if (sscanf(arg, "integrity:%u:", &val) == 1) {
2019 tgt->u.crypt.tag_size = val;
2020 rintegrity = strchr(arg + strlen("integrity:"), ':');
2024 } else if (sscanf(arg, "sector_size:%u", &val) == 1) {
2025 tgt->u.crypt.sector_size = val;
2026 } else /* unknown option */
2030 /* All parameters should be processed */
2036 if (get_flags & DM_ACTIVE_CRYPT_CIPHER) {
2037 r = cipher_dm2c(CONST_CAST(char**)&cipher,
2038 CONST_CAST(char**)&integrity,
2039 rcipher, rintegrity);
2047 *act_flags |= CRYPT_ACTIVATE_KEYRING_KEY;
2049 if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) {
2050 /* we will trust kernel the key_string is in expected format */
2051 if (key_[0] == ':') {
2052 if (sscanf(key_ + 1, "%zu", &key_size) != 1)
2055 key_size = strlen(key_) / 2;
2057 vk = crypt_alloc_volume_key(key_size, NULL);
2063 if (get_flags & DM_ACTIVE_CRYPT_KEY) {
2064 if (key_[0] == ':') {
2065 /* :<key_size>:<key_type>:<key_description> */
2067 endp = strpbrk(key_ + 1, ":");
2069 key_desc = strpbrk(endp + 1, ":");
2075 crypt_volume_key_set_description(vk, key_desc);
2078 for(i = 0; i < vk->keylength; i++) {
2079 memcpy(buffer, &key_[i * 2], 2);
2080 vk->key[i] = strtoul(buffer, &endp, 16);
2081 if (endp != &buffer[2]) {
2089 memset(key_, 0, strlen(key_));
2092 tgt->u.crypt.cipher = cipher;
2094 tgt->u.crypt.integrity = integrity;
2096 tgt->data_device = data_device;
2098 tgt->u.crypt.vk = vk;
2103 device_free(cd, data_device);
2104 crypt_free_volume_key(vk);
2108 static int _dm_target_query_verity(struct crypt_device *cd,
2111 struct dm_target *tgt,
2112 uint32_t *act_flags)
2114 struct crypt_params_verity *vp = NULL;
2118 char *str, *str2, *arg;
2119 unsigned int i, features;
2121 struct device *data_device = NULL, *hash_device = NULL, *fec_device = NULL;
2122 char *hash_name = NULL, *root_hash = NULL, *salt = NULL, *fec_dev_str = NULL;
2123 char *root_hash_sig_key_desc = NULL;
2125 if (get_flags & DM_ACTIVE_VERITY_PARAMS) {
2126 vp = crypt_zalloc(sizeof(*vp));
2131 tgt->type = DM_VERITY;
2132 tgt->direction = TARGET_QUERY;
2133 tgt->u.verity.vp = vp;
2136 val32 = strtoul(params, ¶ms, 10);
2140 vp->hash_type = val32;
2144 str = strsep(¶ms, " ");
2147 if (get_flags & DM_ACTIVE_DEVICE) {
2148 str2 = crypt_lookup_dev(str);
2149 r = device_alloc(cd, &data_device, str2);
2151 if (r < 0 && r != -ENOTBLK)
2158 str = strsep(¶ms, " ");
2161 if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
2162 str2 = crypt_lookup_dev(str);
2163 r = device_alloc(cd, &hash_device, str2);
2165 if (r < 0 && r != -ENOTBLK)
2171 /* data block size*/
2172 val32 = strtoul(params, ¶ms, 10);
2176 vp->data_block_size = val32;
2179 /* hash block size */
2180 val32 = strtoul(params, ¶ms, 10);
2184 vp->hash_block_size = val32;
2188 val64 = strtoull(params, ¶ms, 10);
2192 vp->data_size = val64;
2196 val64 = strtoull(params, ¶ms, 10);
2199 tgt->u.verity.hash_offset = val64;
2202 /* hash algorithm */
2203 str = strsep(¶ms, " ");
2207 hash_name = strdup(str);
2215 str = strsep(¶ms, " ");
2218 len = crypt_hex_to_bytes(str, &str2, 0);
2223 tgt->u.verity.root_hash_size = len;
2224 if (get_flags & DM_ACTIVE_VERITY_ROOT_HASH)
2230 str = strsep(¶ms, " ");
2232 if (!strcmp(str, "-")) {
2236 len = crypt_hex_to_bytes(str, &str2, 0);
2241 vp->salt_size = len;
2248 /* Features section, available since verity target version 1.3 */
2250 /* Number of arguments */
2251 val64 = strtoull(params, ¶ms, 10);
2256 features = (int)val64;
2257 for (i = 0; i < features; i++) {
2261 arg = strsep(¶ms, " ");
2262 if (!strcasecmp(arg, "ignore_corruption"))
2263 *act_flags |= CRYPT_ACTIVATE_IGNORE_CORRUPTION;
2264 else if (!strcasecmp(arg, "restart_on_corruption"))
2265 *act_flags |= CRYPT_ACTIVATE_RESTART_ON_CORRUPTION;
2266 else if (!strcasecmp(arg, "panic_on_corruption"))
2267 *act_flags |= CRYPT_ACTIVATE_PANIC_ON_CORRUPTION;
2268 else if (!strcasecmp(arg, "ignore_zero_blocks"))
2269 *act_flags |= CRYPT_ACTIVATE_IGNORE_ZERO_BLOCKS;
2270 else if (!strcasecmp(arg, "check_at_most_once"))
2271 *act_flags |= CRYPT_ACTIVATE_CHECK_AT_MOST_ONCE;
2272 else if (!strcasecmp(arg, "use_fec_from_device")) {
2273 str = strsep(¶ms, " ");
2274 str2 = crypt_lookup_dev(str);
2275 if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
2276 r = device_alloc(cd, &fec_device, str2);
2277 if (r < 0 && r != -ENOTBLK) {
2288 } else if (!strcasecmp(arg, "fec_start")) {
2289 val64 = strtoull(params, ¶ms, 10);
2292 tgt->u.verity.fec_offset = val64;
2294 vp->fec_area_offset = val64 * vp->hash_block_size;
2296 } else if (!strcasecmp(arg, "fec_blocks")) {
2297 val64 = strtoull(params, ¶ms, 10);
2300 tgt->u.verity.fec_blocks = val64;
2302 } else if (!strcasecmp(arg, "fec_roots")) {
2303 val32 = strtoul(params, ¶ms, 10);
2307 vp->fec_roots = val32;
2309 } else if (!strcasecmp(arg, "root_hash_sig_key_desc")) {
2310 str = strsep(¶ms, " ");
2313 if (!root_hash_sig_key_desc) {
2314 root_hash_sig_key_desc = strdup(str);
2315 if (!root_hash_sig_key_desc) {
2322 vp->flags |= CRYPT_VERITY_ROOT_HASH_SIGNATURE;
2323 } else /* unknown option */
2327 /* All parameters should be processed */
2328 if (params && *params) {
2335 tgt->data_device = data_device;
2337 tgt->u.verity.hash_device = hash_device;
2339 tgt->u.verity.fec_device = fec_device;
2341 tgt->u.verity.root_hash = root_hash;
2342 if (vp && hash_name)
2343 vp->hash_name = hash_name;
2346 if (vp && fec_dev_str)
2347 vp->fec_device = fec_dev_str;
2348 if (root_hash_sig_key_desc)
2349 tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
2353 device_free(cd, data_device);
2354 device_free(cd, hash_device);
2355 device_free(cd, fec_device);
2356 free(root_hash_sig_key_desc);
2365 static int _dm_target_query_integrity(struct crypt_device *cd,
2368 struct dm_target *tgt,
2369 uint32_t *act_flags)
2373 char c, *str, *str2, *arg;
2374 unsigned int i, features, val;
2377 struct device *data_device = NULL, *meta_device = NULL;
2378 char *integrity = NULL, *journal_crypt = NULL, *journal_integrity = NULL;
2379 struct volume_key *vk = NULL;
2381 tgt->type = DM_INTEGRITY;
2382 tgt->direction = TARGET_QUERY;
2385 str = strsep(¶ms, " ");
2386 if (get_flags & DM_ACTIVE_DEVICE) {
2387 str2 = crypt_lookup_dev(str);
2388 r = device_alloc(cd, &data_device, str2);
2390 if (r < 0 && r != -ENOTBLK)
2399 val64 = strtoull(params, ¶ms, 10);
2400 if (!*params || *params != ' ')
2402 tgt->u.integrity.offset = val64;
2405 val32 = strtoul(params, ¶ms, 10);
2406 tgt->u.integrity.tag_size = val32;
2407 if (!*params || *params != ' ')
2411 c = toupper(*(++params));
2412 if (!*params || *(++params) != ' ' || (c != 'D' && c != 'J' && c != 'R' && c != 'B'))
2415 *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
2417 *act_flags |= CRYPT_ACTIVATE_RECOVERY;
2419 *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL;
2420 *act_flags |= CRYPT_ACTIVATE_NO_JOURNAL_BITMAP;
2423 tgt->u.integrity.sector_size = SECTOR_SIZE;
2425 /* Features section */
2427 /* Number of arguments */
2428 val64 = strtoull(params, ¶ms, 10);
2433 features = (int)val64;
2434 for (i = 0; i < features; i++) {
2438 arg = strsep(¶ms, " ");
2439 if (sscanf(arg, "journal_sectors:%u", &val) == 1)
2440 tgt->u.integrity.journal_size = val * SECTOR_SIZE;
2441 else if (sscanf(arg, "journal_watermark:%u", &val) == 1)
2442 tgt->u.integrity.journal_watermark = val;
2443 else if (sscanf(arg, "sectors_per_bit:%" PRIu64, &val64) == 1) {
2444 if (val64 > UINT_MAX)
2446 /* overloaded value for bitmap mode */
2447 tgt->u.integrity.journal_watermark = (unsigned int)val64;
2448 } else if (sscanf(arg, "commit_time:%u", &val) == 1)
2449 tgt->u.integrity.journal_commit_time = val;
2450 else if (sscanf(arg, "bitmap_flush_interval:%u", &val) == 1)
2451 /* overloaded value for bitmap mode */
2452 tgt->u.integrity.journal_commit_time = val;
2453 else if (sscanf(arg, "interleave_sectors:%u", &val) == 1)
2454 tgt->u.integrity.interleave_sectors = val;
2455 else if (sscanf(arg, "block_size:%u", &val) == 1)
2456 tgt->u.integrity.sector_size = val;
2457 else if (sscanf(arg, "buffer_sectors:%u", &val) == 1)
2458 tgt->u.integrity.buffer_sectors = val;
2459 else if (!strncmp(arg, "internal_hash:", 14) && !integrity) {
2461 arg = strsep(&str, ":");
2462 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
2463 integrity = strdup(arg);
2471 len = crypt_hex_to_bytes(str, &str2, 1);
2478 if (get_flags & DM_ACTIVE_CRYPT_KEY) {
2479 vk = crypt_alloc_volume_key(len, str2);
2482 } else if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) {
2483 vk = crypt_alloc_volume_key(len, NULL);
2487 crypt_safe_free(str2);
2491 } else if (!strncmp(arg, "meta_device:", 12) && !meta_device) {
2492 if (get_flags & DM_ACTIVE_DEVICE) {
2493 str = crypt_lookup_dev(&arg[12]);
2494 r = device_alloc(cd, &meta_device, str);
2496 if (r < 0 && r != -ENOTBLK)
2499 } else if (!strncmp(arg, "journal_crypt:", 14) && !journal_crypt) {
2501 arg = strsep(&str, ":");
2502 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
2503 journal_crypt = strdup(arg);
2504 if (!journal_crypt) {
2509 } else if (!strncmp(arg, "journal_mac:", 12) && !journal_integrity) {
2511 arg = strsep(&str, ":");
2512 if (get_flags & DM_ACTIVE_INTEGRITY_PARAMS) {
2513 journal_integrity = strdup(arg);
2514 if (!journal_integrity) {
2519 } else if (!strcmp(arg, "recalculate")) {
2520 *act_flags |= CRYPT_ACTIVATE_RECALCULATE;
2521 } else if (!strcmp(arg, "fix_padding")) {
2522 tgt->u.integrity.fix_padding = true;
2523 } else if (!strcmp(arg, "fix_hmac")) {
2524 tgt->u.integrity.fix_hmac = true;
2525 } else if (!strcmp(arg, "legacy_recalculate")) {
2526 tgt->u.integrity.legacy_recalc = true;
2527 } else if (!strcmp(arg, "allow_discards")) {
2528 *act_flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
2529 } else /* unknown option */
2533 /* All parameters should be processed */
2534 if (params && *params) {
2541 tgt->data_device = data_device;
2543 tgt->u.integrity.meta_device = meta_device;
2545 tgt->u.integrity.integrity = integrity;
2547 tgt->u.integrity.journal_crypt = journal_crypt;
2548 if (journal_integrity)
2549 tgt->u.integrity.journal_integrity = journal_integrity;
2551 tgt->u.integrity.vk = vk;
2554 device_free(cd, data_device);
2555 device_free(cd, meta_device);
2557 free(journal_crypt);
2558 free(journal_integrity);
2559 crypt_free_volume_key(vk);
2563 static int _dm_target_query_linear(struct crypt_device *cd, struct dm_target *tgt,
2564 uint32_t get_flags, char *params)
2567 char *rdevice, *arg;
2569 struct device *device = NULL;
2572 rdevice = strsep(¶ms, " ");
2573 if (get_flags & DM_ACTIVE_DEVICE) {
2574 arg = crypt_lookup_dev(rdevice);
2575 r = device_alloc(cd, &device, arg);
2577 if (r < 0 && r != -ENOTBLK)
2586 val64 = strtoull(params, ¶ms, 10);
2588 /* params should be empty now */
2592 tgt->type = DM_LINEAR;
2593 tgt->direction = TARGET_QUERY;
2594 tgt->data_device = device;
2595 tgt->u.linear.offset = val64;
2599 device_free(cd, device);
2603 static int _dm_target_query_error(struct crypt_device *cd, struct dm_target *tgt)
2605 tgt->type = DM_ERROR;
2606 tgt->direction = TARGET_QUERY;
2611 static int _dm_target_query_zero(struct crypt_device *cd, struct dm_target *tgt)
2613 tgt->type = DM_ZERO;
2614 tgt->direction = TARGET_QUERY;
2620 * on error retval has to be negative
2622 * also currently any _dm_target_query fn does not perform cleanup on error
2624 static int dm_target_query(struct crypt_device *cd, struct dm_target *tgt, const uint64_t *start,
2625 const uint64_t *length, const char *target_type,
2626 char *params, uint32_t get_flags, uint32_t *act_flags)
2630 if (!strcmp(target_type, DM_CRYPT_TARGET))
2631 r = _dm_target_query_crypt(cd, get_flags, params, tgt, act_flags);
2632 else if (!strcmp(target_type, DM_VERITY_TARGET))
2633 r = _dm_target_query_verity(cd, get_flags, params, tgt, act_flags);
2634 else if (!strcmp(target_type, DM_INTEGRITY_TARGET))
2635 r = _dm_target_query_integrity(cd, get_flags, params, tgt, act_flags);
2636 else if (!strcmp(target_type, DM_LINEAR_TARGET))
2637 r = _dm_target_query_linear(cd, tgt, get_flags, params);
2638 else if (!strcmp(target_type, DM_ERROR_TARGET))
2639 r = _dm_target_query_error(cd, tgt);
2640 else if (!strcmp(target_type, DM_ZERO_TARGET))
2641 r = _dm_target_query_zero(cd, tgt);
2644 tgt->offset = *start;
2645 tgt->size = *length;
2651 static int _dm_query_device(struct crypt_device *cd, const char *name,
2652 uint32_t get_flags, struct crypt_dm_active_device *dmd)
2654 struct dm_target *t;
2655 struct dm_task *dmt;
2657 uint64_t start, length;
2658 char *target_type, *params;
2659 const char *tmp_uuid;
2665 if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
2667 if (!dm_task_secure_data(dmt))
2669 if (!dm_task_set_name(dmt, name))
2672 if (!dm_task_run(dmt))
2676 if (!dm_task_get_info(dmt, &dmi))
2684 if (dmi.target_count <= 0) {
2689 /* Never allow to return empty key */
2690 if ((get_flags & DM_ACTIVE_CRYPT_KEY) && dmi.suspended) {
2691 log_dbg(cd, "Cannot read volume key while suspended.");
2696 r = dm_targets_allocate(&dmd->segment, dmi.target_count);
2701 next = dm_get_next_target(dmt, next, &start, &length,
2702 &target_type, ¶ms);
2704 r = dm_target_query(cd, t, &start, &length, target_type, params, get_flags, &dmd->flags);
2705 if (!r && t->type == DM_VERITY) {
2706 r = _dm_status_verity_ok(cd, name);
2708 dmd->flags |= CRYPT_ACTIVATE_CORRUPTED;
2713 log_err(cd, _("Failed to query dm-%s segment."), target_type);
2717 dmd->size += length;
2719 } while (next && t);
2722 dmd->flags |= CRYPT_ACTIVATE_READONLY;
2725 dmd->flags |= CRYPT_ACTIVATE_SUSPENDED;
2727 tmp_uuid = dm_task_get_uuid(dmt);
2729 dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
2730 else if (get_flags & DM_ACTIVE_UUID) {
2731 if (!strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
2732 dmd->uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
2736 #if (HAVE_DECL_DM_DEVICE_HAS_HOLDERS && HAVE_DECL_DM_DEVICE_HAS_MOUNTED_FS)
2737 if (get_flags & DM_ACTIVE_HOLDERS)
2738 dmd->holders = (dm_device_has_mounted_fs(dmi.major, dmi.minor) ||
2739 dm_device_has_holders(dmi.major, dmi.minor));
2742 r = (dmi.open_count > 0);
2745 dm_task_destroy(dmt);
2748 dm_targets_free(cd, dmd);
2753 int dm_query_device(struct crypt_device *cd, const char *name,
2754 uint32_t get_flags, struct crypt_dm_active_device *dmd)
2761 memset(dmd, 0, sizeof(*dmd));
2763 if (dm_init_context(cd, DM_UNKNOWN))
2766 r = _dm_query_device(cd, name, get_flags, dmd);
2772 static int _process_deps(struct crypt_device *cd, const char *prefix, struct dm_deps *deps, char **names, size_t names_offset, size_t names_length)
2774 #if HAVE_DECL_DM_DEVICE_GET_NAME
2775 struct crypt_dm_active_device dmd;
2776 char dmname[PATH_MAX];
2778 int r, major, minor, count = 0;
2780 if (!prefix || !deps)
2783 for (i = 0; i < deps->count; i++) {
2784 major = major(deps->device[i]);
2785 if (!dm_is_dm_major(major))
2788 minor = minor(deps->device[i]);
2789 if (!dm_device_get_name(major, minor, 0, dmname, PATH_MAX))
2792 memset(&dmd, 0, sizeof(dmd));
2793 r = _dm_query_device(cd, dmname, DM_ACTIVE_UUID, &dmd);
2798 strncmp(prefix, dmd.uuid, strlen(prefix)) ||
2799 crypt_string_in(dmname, names, names_length))
2802 dm_targets_free(cd, &dmd);
2803 free(CONST_CAST(void*)dmd.uuid);
2805 if ((size_t)count >= (names_length - names_offset))
2808 if (*dmname && !(names[names_offset + count++] = strdup(dmname)))
2818 int dm_device_deps(struct crypt_device *cd, const char *name, const char *prefix, char **names, size_t names_length)
2820 struct dm_task *dmt;
2822 struct dm_deps *deps;
2824 size_t i, last = 0, offset = 0;
2826 if (!name || !names_length || !names)
2829 if (dm_init_context(cd, DM_UNKNOWN))
2833 if (!(dmt = dm_task_create(DM_DEVICE_DEPS)))
2835 if (!dm_task_set_name(dmt, name))
2839 if (!dm_task_run(dmt))
2843 if (!dm_task_get_info(dmt, &dmi))
2845 if (!(deps = dm_task_get_deps(dmt)))
2852 r = _process_deps(cd, prefix, deps, names, offset, names_length - 1);
2856 dm_task_destroy(dmt);
2860 name = names[last++];
2866 for (i = 0; i < names_length - 1; i++)
2872 dm_task_destroy(dmt);
2878 static int _dm_message(const char *name, const char *msg)
2881 struct dm_task *dmt;
2883 if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
2886 if (!dm_task_secure_data(dmt))
2889 if (name && !dm_task_set_name(dmt, name))
2892 if (!dm_task_set_sector(dmt, (uint64_t) 0))
2895 if (!dm_task_set_message(dmt, msg))
2898 r = dm_task_run(dmt);
2900 dm_task_destroy(dmt);
2904 int dm_suspend_device(struct crypt_device *cd, const char *name, uint32_t dmflags)
2909 if (dm_init_context(cd, DM_UNKNOWN))
2912 if (dmflags & DM_SUSPEND_WIPE_KEY) {
2913 if (dm_flags(cd, DM_CRYPT, &dmt_flags))
2916 if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED))
2922 if (!_dm_simple(DM_DEVICE_SUSPEND, name, dmflags))
2925 if (dmflags & DM_SUSPEND_WIPE_KEY) {
2926 if (!_dm_message(name, "key wipe")) {
2927 _dm_resume_device(name, 0);
2938 int dm_resume_device(struct crypt_device *cd, const char *name, uint32_t dmflags)
2942 if (dm_init_context(cd, DM_UNKNOWN))
2945 r = _dm_resume_device(name, dmflags);
2952 int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
2953 const struct volume_key *vk)
2960 if (dm_init_context(cd, DM_CRYPT) || dm_flags(cd, DM_CRYPT, &dmt_flags))
2963 if (!(dmt_flags & DM_KEY_WIPE_SUPPORTED))
2967 msg_size = 11; // key set -
2968 else if (vk->key_description)
2969 msg_size = strlen(vk->key_description) + int_log10(vk->keylength) + 18;
2971 msg_size = vk->keylength * 2 + 10; // key set <key>
2973 msg = crypt_safe_alloc(msg_size);
2979 strcpy(msg, "key set ");
2981 snprintf(msg + 8, msg_size - 8, "-");
2982 else if (vk->key_description)
2983 snprintf(msg + 8, msg_size - 8, ":%zu:logon:%s", vk->keylength, vk->key_description);
2985 hex_key(&msg[8], vk->keylength, vk->key);
2987 if (!_dm_message(name, msg) ||
2988 _dm_resume_device(name, 0)) {
2994 crypt_safe_free(msg);
2999 const char *dm_get_dir(void)
3004 int dm_is_dm_device(int major)
3006 return dm_is_dm_major((uint32_t)major);
3009 int dm_is_dm_kernel_name(const char *name)
3011 return strncmp(name, "dm-", 3) ? 0 : 1;
3014 int dm_crypt_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
3015 struct device *data_device, struct volume_key *vk, const char *cipher,
3016 uint64_t iv_offset, uint64_t data_offset, const char *integrity, uint32_t tag_size,
3017 uint32_t sector_size)
3022 char *dm_integrity = NULL;
3025 /* Space for IV metadata only */
3026 dm_integrity = strdup(integrity ?: "none");
3027 if (!dm_integrity) {
3033 tgt->data_device = data_device;
3035 tgt->type = DM_CRYPT;
3036 tgt->direction = TARGET_SET;
3037 tgt->u.crypt.vk = vk;
3038 tgt->offset = seg_offset;
3039 tgt->size = seg_size;
3041 tgt->u.crypt.cipher = cipher;
3042 tgt->u.crypt.integrity = dm_integrity;
3043 tgt->u.crypt.iv_offset = iv_offset;
3044 tgt->u.crypt.offset = data_offset;
3045 tgt->u.crypt.tag_size = tag_size;
3046 tgt->u.crypt.sector_size = sector_size;
3055 int dm_verity_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
3056 struct device *data_device, struct device *hash_device, struct device *fec_device,
3057 const char *root_hash, uint32_t root_hash_size, const char* root_hash_sig_key_desc,
3058 uint64_t hash_offset_block, uint64_t fec_blocks, struct crypt_params_verity *vp)
3060 if (!data_device || !hash_device || !vp)
3063 tgt->type = DM_VERITY;
3064 tgt->direction = TARGET_SET;
3065 tgt->offset = seg_offset;
3066 tgt->size = seg_size;
3067 tgt->data_device = data_device;
3069 tgt->u.verity.hash_device = hash_device;
3070 tgt->u.verity.fec_device = fec_device;
3071 tgt->u.verity.root_hash = root_hash;
3072 tgt->u.verity.root_hash_size = root_hash_size;
3073 tgt->u.verity.root_hash_sig_key_desc = root_hash_sig_key_desc;
3074 tgt->u.verity.hash_offset = hash_offset_block;
3075 tgt->u.verity.fec_offset = vp->fec_area_offset / vp->hash_block_size;
3076 tgt->u.verity.fec_blocks = fec_blocks;
3077 tgt->u.verity.vp = vp;
3082 int dm_integrity_target_set(struct crypt_device *cd,
3083 struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
3084 struct device *meta_device,
3085 struct device *data_device, uint64_t tag_size, uint64_t offset,
3086 uint32_t sector_size, struct volume_key *vk,
3087 struct volume_key *journal_crypt_key, struct volume_key *journal_mac_key,
3088 const struct crypt_params_integrity *ip)
3095 _dm_check_versions(cd, DM_INTEGRITY);
3097 tgt->type = DM_INTEGRITY;
3098 tgt->direction = TARGET_SET;
3099 tgt->offset = seg_offset;
3100 tgt->size = seg_size;
3101 tgt->data_device = data_device;
3102 if (meta_device != data_device)
3103 tgt->u.integrity.meta_device = meta_device;
3104 tgt->u.integrity.tag_size = tag_size;
3105 tgt->u.integrity.offset = offset;
3106 tgt->u.integrity.sector_size = sector_size;
3108 tgt->u.integrity.vk = vk;
3109 tgt->u.integrity.journal_crypt_key = journal_crypt_key;
3110 tgt->u.integrity.journal_integrity_key = journal_mac_key;
3112 if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
3113 (dmi_flags & DM_INTEGRITY_FIX_PADDING_SUPPORTED) &&
3114 !(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING))
3115 tgt->u.integrity.fix_padding = true;
3117 if (!dm_flags(cd, DM_INTEGRITY, &dmi_flags) &&
3118 (dmi_flags & DM_INTEGRITY_FIX_HMAC_SUPPORTED) &&
3119 !(crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_HMAC))
3120 tgt->u.integrity.fix_hmac = true;
3122 /* This flag can be backported, just try to set it always */
3123 if (crypt_get_compatibility(cd) & CRYPT_COMPAT_LEGACY_INTEGRITY_RECALC)
3124 tgt->u.integrity.legacy_recalc = true;
3127 tgt->u.integrity.journal_size = ip->journal_size;
3128 tgt->u.integrity.journal_watermark = ip->journal_watermark;
3129 tgt->u.integrity.journal_commit_time = ip->journal_commit_time;
3130 tgt->u.integrity.interleave_sectors = ip->interleave_sectors;
3131 tgt->u.integrity.buffer_sectors = ip->buffer_sectors;
3132 tgt->u.integrity.journal_integrity = ip->journal_integrity;
3133 tgt->u.integrity.journal_crypt = ip->journal_crypt;
3134 tgt->u.integrity.integrity = ip->integrity;
3140 int dm_linear_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size,
3141 struct device *data_device, uint64_t data_offset)
3146 tgt->type = DM_LINEAR;
3147 tgt->direction = TARGET_SET;
3148 tgt->offset = seg_offset;
3149 tgt->size = seg_size;
3150 tgt->data_device = data_device;
3152 tgt->u.linear.offset = data_offset;
3157 int dm_zero_target_set(struct dm_target *tgt, uint64_t seg_offset, uint64_t seg_size)
3159 tgt->type = DM_ZERO;
3160 tgt->direction = TARGET_SET;
3161 tgt->offset = seg_offset;
3162 tgt->size = seg_size;