Imported Upstream version 1.6.7
[platform/upstream/cryptsetup.git] / lib / libdevmapper.c
1 /*
2  * libdevmapper - device-mapper backend for cryptsetup
3  *
4  * Copyright (C) 2004, Jana Saout <jana@saout.de>
5  * Copyright (C) 2004-2007, Clemens Fruhwirth <clemens@endorphin.org>
6  * Copyright (C) 2009-2015, Red Hat, Inc. All rights reserved.
7  * Copyright (C) 2009-2015, Milan Broz
8  *
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.
13  *
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.
18  *
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.
22  */
23
24 #include <stdio.h>
25 #include <dirent.h>
26 #include <errno.h>
27 #include <libdevmapper.h>
28 #include <fcntl.h>
29 #include <linux/fs.h>
30 #include <uuid/uuid.h>
31
32 #include "internal.h"
33
34 #define DM_UUID_LEN             129
35 #define DM_UUID_PREFIX          "CRYPT-"
36 #define DM_UUID_PREFIX_LEN      6
37 #define DM_CRYPT_TARGET         "crypt"
38 #define DM_VERITY_TARGET        "verity"
39 #define RETRY_COUNT             5
40
41 /* Set if dm-crypt version was probed */
42 static int _dm_crypt_checked = 0;
43 static int _quiet_log = 0;
44 static uint32_t _dm_crypt_flags = 0;
45
46 static struct crypt_device *_context = NULL;
47 static int _dm_use_count = 0;
48
49 /* Check if we have DM flag to instruct kernel to force wipe buffers */
50 #if !HAVE_DECL_DM_TASK_SECURE_DATA
51 static int dm_task_secure_data(struct dm_task *dmt) { return 1; }
52 #endif
53
54 /* Compatibility for old device-mapper without udev support */
55 #if HAVE_DECL_DM_UDEV_DISABLE_DISK_RULES_FLAG
56 #define CRYPT_TEMP_UDEV_FLAGS   DM_UDEV_DISABLE_SUBSYSTEM_RULES_FLAG | \
57                                 DM_UDEV_DISABLE_DISK_RULES_FLAG | \
58                                 DM_UDEV_DISABLE_OTHER_RULES_FLAG
59 #define _dm_task_set_cookie     dm_task_set_cookie
60 #define _dm_udev_wait           dm_udev_wait
61 #else
62 #define CRYPT_TEMP_UDEV_FLAGS   0
63 static int _dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie, uint16_t flags) { return 0; }
64 static int _dm_udev_wait(uint32_t cookie) { return 0; };
65 #endif
66
67 static int _dm_use_udev(void)
68 {
69 #ifdef USE_UDEV /* cannot be enabled if devmapper is too old */
70         return dm_udev_get_sync_support();
71 #else
72         return 0;
73 #endif
74 }
75
76 __attribute__((format(printf, 4, 5)))
77 static void set_dm_error(int level,
78                          const char *file __attribute__((unused)),
79                          int line __attribute__((unused)),
80                          const char *f, ...)
81 {
82         char *msg = NULL;
83         va_list va;
84
85         va_start(va, f);
86         if (vasprintf(&msg, f, va) > 0) {
87                 if (level < 4 && !_quiet_log) {
88                         log_err(_context, "%s", msg);
89                         log_err(_context, "\n");
90                 } else {
91                         /* We do not use DM visual stack backtrace here */
92                         if (strncmp(msg, "<backtrace>", 11))
93                                 log_dbg("%s", msg);
94                 }
95         }
96         free(msg);
97         va_end(va);
98 }
99
100 static int _dm_simple(int task, const char *name, int udev_wait);
101
102 static int _dm_satisfies_version(unsigned target_maj, unsigned target_min,
103                                  unsigned actual_maj, unsigned actual_min)
104 {
105         if (actual_maj > target_maj)
106                 return 1;
107
108         if (actual_maj == target_maj && actual_min >= target_min)
109                 return 1;
110
111         return 0;
112 }
113
114 static void _dm_set_crypt_compat(const char *dm_version, unsigned crypt_maj,
115                                  unsigned crypt_min, unsigned crypt_patch)
116 {
117         unsigned dm_maj, dm_min, dm_patch;
118
119         if (sscanf(dm_version, "%u.%u.%u", &dm_maj, &dm_min, &dm_patch) != 3)
120                 dm_maj = dm_min = dm_patch = 0;
121
122         log_dbg("Detected dm-crypt version %i.%i.%i, dm-ioctl version %u.%u.%u.",
123                 crypt_maj, crypt_min, crypt_patch, dm_maj, dm_min, dm_patch);
124
125         if (_dm_satisfies_version(1, 2, crypt_maj, crypt_min))
126                 _dm_crypt_flags |= DM_KEY_WIPE_SUPPORTED;
127         else
128                 log_dbg("Suspend and resume disabled, no wipe key support.");
129
130         if (_dm_satisfies_version(1, 10, crypt_maj, crypt_min))
131                 _dm_crypt_flags |= DM_LMK_SUPPORTED;
132
133         if (_dm_satisfies_version(4, 20, dm_maj, dm_min))
134                 _dm_crypt_flags |= DM_SECURE_SUPPORTED;
135
136         /* not perfect, 2.6.33 supports with 1.7.0 */
137         if (_dm_satisfies_version(1, 8, crypt_maj, crypt_min))
138                 _dm_crypt_flags |= DM_PLAIN64_SUPPORTED;
139
140         if (_dm_satisfies_version(1, 11, crypt_maj, crypt_min))
141                 _dm_crypt_flags |= DM_DISCARDS_SUPPORTED;
142
143         if (_dm_satisfies_version(1, 13, crypt_maj, crypt_min))
144                 _dm_crypt_flags |= DM_TCW_SUPPORTED;
145
146         if (_dm_satisfies_version(1, 14, crypt_maj, crypt_min)) {
147                 _dm_crypt_flags |= DM_SAME_CPU_CRYPT_SUPPORTED;
148                 _dm_crypt_flags |= DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED;
149         }
150
151         /* Repeat test if dm-crypt is not present */
152         if (crypt_maj > 0)
153                 _dm_crypt_checked = 1;
154 }
155
156 static void _dm_set_verity_compat(const char *dm_version, unsigned verity_maj,
157                                    unsigned verity_min, unsigned verity_patch)
158 {
159         if (verity_maj > 0)
160                 _dm_crypt_flags |= DM_VERITY_SUPPORTED;
161
162         log_dbg("Detected dm-verity version %i.%i.%i.",
163                 verity_maj, verity_min, verity_patch);
164 }
165
166 static int _dm_check_versions(void)
167 {
168         struct dm_task *dmt;
169         struct dm_versions *target, *last_target;
170         char dm_version[16];
171         int r = 0;
172
173         if (_dm_crypt_checked)
174                 return 1;
175
176         /* Shut up DM while checking */
177         _quiet_log = 1;
178
179         /* FIXME: add support to DM so it forces crypt target module load here */
180         if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
181                 goto out;
182
183         if (!dm_task_run(dmt))
184                 goto out;
185
186         if (!dm_task_get_driver_version(dmt, dm_version, sizeof(dm_version)))
187                 goto out;
188
189         target = dm_task_get_versions(dmt);
190         do {
191                 last_target = target;
192                 if (!strcmp(DM_CRYPT_TARGET, target->name)) {
193                         _dm_set_crypt_compat(dm_version,
194                                              (unsigned)target->version[0],
195                                              (unsigned)target->version[1],
196                                              (unsigned)target->version[2]);
197                 } else if (!strcmp(DM_VERITY_TARGET, target->name)) {
198                         _dm_set_verity_compat(dm_version,
199                                              (unsigned)target->version[0],
200                                              (unsigned)target->version[1],
201                                              (unsigned)target->version[2]);
202                 }
203                 target = (struct dm_versions *)((char *) target + target->next);
204         } while (last_target != target);
205
206         r = 1;
207         log_dbg("Device-mapper backend running with UDEV support %sabled.",
208                 _dm_use_udev() ? "en" : "dis");
209 out:
210         if (dmt)
211                 dm_task_destroy(dmt);
212
213         _quiet_log = 0;
214         return r;
215 }
216
217 uint32_t dm_flags(void)
218 {
219         _dm_check_versions();
220         return _dm_crypt_flags;
221 }
222
223 /* This doesn't run any kernel checks, just set up userspace libdevmapper */
224 void dm_backend_init(void)
225 {
226         if (!_dm_use_count++) {
227                 log_dbg("Initialising device-mapper backend library.");
228                 dm_log_init(set_dm_error);
229                 dm_log_init_verbose(10);
230         }
231 }
232
233 void dm_backend_exit(void)
234 {
235         if (_dm_use_count && (!--_dm_use_count)) {
236                 log_dbg("Releasing device-mapper backend.");
237                 dm_log_init_verbose(0);
238                 dm_log_init(NULL);
239                 dm_lib_release();
240         }
241 }
242
243 /*
244  * libdevmapper is not context friendly, switch context on every DM call.
245  * FIXME: this is not safe if called in parallel but neither is DM lib.
246  */
247 static int dm_init_context(struct crypt_device *cd)
248 {
249         _context = cd;
250         if (!_dm_check_versions()) {
251                 if (getuid() || geteuid())
252                         log_err(cd, _("Cannot initialize device-mapper, "
253                                       "running as non-root user.\n"));
254                 else
255                         log_err(cd, _("Cannot initialize device-mapper. "
256                                       "Is dm_mod kernel module loaded?\n"));
257                 _context = NULL;
258                 return -ENOTSUP;
259         }
260         return 0;
261 }
262 static void dm_exit_context(void)
263 {
264         _context = NULL;
265 }
266
267 /* Return path to DM device */
268 char *dm_device_path(const char *prefix, int major, int minor)
269 {
270         struct dm_task *dmt;
271         const char *name;
272         char path[PATH_MAX];
273
274         if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
275                 return NULL;
276         if (!dm_task_set_minor(dmt, minor) ||
277             !dm_task_set_major(dmt, major) ||
278             !dm_task_run(dmt) ||
279             !(name = dm_task_get_name(dmt))) {
280                 dm_task_destroy(dmt);
281                 return NULL;
282         }
283
284         if (snprintf(path, sizeof(path), "%s%s", prefix ?: "", name) < 0)
285                 path[0] = '\0';
286
287         dm_task_destroy(dmt);
288
289         return strdup(path);
290 }
291
292 static void hex_key(char *hexkey, size_t key_size, const char *key)
293 {
294         unsigned i;
295
296         for(i = 0; i < key_size; i++)
297                 sprintf(&hexkey[i * 2], "%02x", (unsigned char)key[i]);
298 }
299
300 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt */
301 static char *get_dm_crypt_params(struct crypt_dm_active_device *dmd, uint32_t flags)
302 {
303         int r, max_size, null_cipher = 0, num_options = 0;
304         char *params, *hexkey;
305         char features[256];
306
307         if (!dmd)
308                 return NULL;
309
310         if (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS)
311                 num_options++;
312         if (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT)
313                 num_options++;
314         if (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS)
315                 num_options++;
316
317         if (num_options)
318                 snprintf(features, sizeof(features)-1, " %d%s%s%s", num_options,
319                 (flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? " allow_discards" : "",
320                 (flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? " same_cpu_crypt" : "",
321                 (flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? " submit_from_crypt_cpus" : "");
322         else
323                 *features = '\0';
324
325         if (!strncmp(dmd->u.crypt.cipher, "cipher_null-", 12))
326                 null_cipher = 1;
327
328         hexkey = crypt_safe_alloc(null_cipher ? 2 : (dmd->u.crypt.vk->keylength * 2 + 1));
329         if (!hexkey)
330                 return NULL;
331
332         if (null_cipher)
333                 strncpy(hexkey, "-", 2);
334         else
335                 hex_key(hexkey, dmd->u.crypt.vk->keylength, dmd->u.crypt.vk->key);
336
337         max_size = strlen(hexkey) + strlen(dmd->u.crypt.cipher) +
338                    strlen(device_block_path(dmd->data_device)) +
339                    strlen(features) + 64;
340         params = crypt_safe_alloc(max_size);
341         if (!params)
342                 goto out;
343
344         r = snprintf(params, max_size, "%s %s %" PRIu64 " %s %" PRIu64 "%s",
345                      dmd->u.crypt.cipher, hexkey, dmd->u.crypt.iv_offset,
346                      device_block_path(dmd->data_device), dmd->u.crypt.offset,
347                      features);
348         if (r < 0 || r >= max_size) {
349                 crypt_safe_free(params);
350                 params = NULL;
351         }
352 out:
353         crypt_safe_free(hexkey);
354         return params;
355 }
356
357 /* https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity */
358 static char *get_dm_verity_params(struct crypt_params_verity *vp,
359                                    struct crypt_dm_active_device *dmd)
360 {
361         int max_size, r;
362         char *params = NULL, *hexroot = NULL, *hexsalt = NULL;
363
364         if (!vp || !dmd)
365                 return NULL;
366
367         hexroot = crypt_safe_alloc(dmd->u.verity.root_hash_size * 2 + 1);
368         if (!hexroot)
369                 goto out;
370         hex_key(hexroot, dmd->u.verity.root_hash_size, dmd->u.verity.root_hash);
371
372         hexsalt = crypt_safe_alloc(vp->salt_size ? vp->salt_size * 2 + 1 : 2);
373         if (!hexsalt)
374                 goto out;
375         if (vp->salt_size)
376                 hex_key(hexsalt, vp->salt_size, vp->salt);
377         else
378                 strncpy(hexsalt, "-", 2);
379
380         max_size = strlen(hexroot) + strlen(hexsalt) +
381                    strlen(device_block_path(dmd->data_device)) +
382                    strlen(device_block_path(dmd->u.verity.hash_device)) +
383                    strlen(vp->hash_name) + 128;
384
385         params = crypt_safe_alloc(max_size);
386         if (!params)
387                 goto out;
388
389         r = snprintf(params, max_size,
390                      "%u %s %s %u %u %" PRIu64 " %" PRIu64 " %s %s %s",
391                      vp->hash_type, device_block_path(dmd->data_device),
392                      device_block_path(dmd->u.verity.hash_device),
393                      vp->data_block_size, vp->hash_block_size,
394                      vp->data_size, dmd->u.verity.hash_offset,
395                      vp->hash_name, hexroot, hexsalt);
396         if (r < 0 || r >= max_size) {
397                 crypt_safe_free(params);
398                 params = NULL;
399         }
400 out:
401         crypt_safe_free(hexroot);
402         crypt_safe_free(hexsalt);
403         return params;
404
405 }
406
407 /* DM helpers */
408 static int _dm_simple(int task, const char *name, int udev_wait)
409 {
410         int r = 0;
411         struct dm_task *dmt;
412         uint32_t cookie = 0;
413
414         if (!_dm_use_udev())
415                 udev_wait = 0;
416
417         if (!(dmt = dm_task_create(task)))
418                 return 0;
419
420         if (name && !dm_task_set_name(dmt, name))
421                 goto out;
422
423 #if HAVE_DECL_DM_TASK_RETRY_REMOVE
424         /* Used only in DM_DEVICE_REMOVE */
425         if (name && !dm_task_retry_remove(dmt))
426                 goto out;
427 #endif
428         if (udev_wait && !_dm_task_set_cookie(dmt, &cookie, 0))
429                 goto out;
430
431         r = dm_task_run(dmt);
432
433         if (udev_wait)
434                 (void)_dm_udev_wait(cookie);
435
436       out:
437         dm_task_destroy(dmt);
438         return r;
439 }
440
441 static int _error_device(const char *name, size_t size)
442 {
443         struct dm_task *dmt;
444         int r = 0;
445
446         if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
447                 return 0;
448
449         if (!dm_task_set_name(dmt, name))
450                 goto error;
451
452         if (!dm_task_add_target(dmt, UINT64_C(0), size, "error", ""))
453                 goto error;
454
455         if (!dm_task_set_ro(dmt))
456                 goto error;
457
458         if (!dm_task_no_open_count(dmt))
459                 goto error;
460
461         if (!dm_task_run(dmt))
462                 goto error;
463
464         if (!_dm_simple(DM_DEVICE_RESUME, name, 1)) {
465                 _dm_simple(DM_DEVICE_CLEAR, name, 0);
466                 goto error;
467         }
468
469         r = 1;
470
471 error:
472         dm_task_destroy(dmt);
473         return r;
474 }
475
476 int dm_remove_device(struct crypt_device *cd, const char *name,
477                      int force, uint64_t size)
478 {
479         int r = -EINVAL;
480         int retries = force ? RETRY_COUNT : 1;
481         int error_target = 0;
482
483         if (!name || (force && !size))
484                 return -EINVAL;
485
486         if (dm_init_context(cd))
487                 return -ENOTSUP;
488
489         do {
490                 r = _dm_simple(DM_DEVICE_REMOVE, name, 1) ? 0 : -EINVAL;
491                 if (--retries && r) {
492                         log_dbg("WARNING: other process locked internal device %s, %s.",
493                                 name, retries ? "retrying remove" : "giving up");
494                         sleep(1);
495                         if (force && !error_target) {
496                                 /* If force flag is set, replace device with error, read-only target.
497                                  * it should stop processes from reading it and also removed underlying
498                                  * device from mapping, so it is usable again.
499                                  * Force flag should be used only for temporary devices, which are
500                                  * intended to work inside cryptsetup only!
501                                  * Anyway, if some process try to read temporary cryptsetup device,
502                                  * it is bug - no other process should try touch it (e.g. udev).
503                                  */
504                                 _error_device(name, size);
505                                 error_target = 1;
506                         }
507                 }
508         } while (r == -EINVAL && retries);
509
510         dm_task_update_nodes();
511         dm_exit_context();
512
513         return r;
514 }
515
516 #define UUID_LEN 37 /* 36 + \0, libuuid ... */
517 /*
518  * UUID has format: CRYPT-<devicetype>-[<uuid>-]<device name>
519  * CRYPT-PLAIN-name
520  * CRYPT-LUKS1-00000000000000000000000000000000-name
521  * CRYPT-TEMP-name
522  */
523 static int dm_prepare_uuid(const char *name, const char *type, const char *uuid, char *buf, size_t buflen)
524 {
525         char *ptr, uuid2[UUID_LEN] = {0};
526         uuid_t uu;
527         unsigned i = 0;
528
529         /* Remove '-' chars */
530         if (uuid) {
531                 if (uuid_parse(uuid, uu) < 0) {
532                         log_dbg("Requested UUID %s has invalid format.", uuid);
533                         return 0;
534                 }
535
536                 for (ptr = uuid2, i = 0; i < UUID_LEN; i++)
537                         if (uuid[i] != '-') {
538                                 *ptr = uuid[i];
539                                 ptr++;
540                         }
541         }
542
543         i = snprintf(buf, buflen, DM_UUID_PREFIX "%s%s%s%s%s",
544                 type ?: "", type ? "-" : "",
545                 uuid2[0] ? uuid2 : "", uuid2[0] ? "-" : "",
546                 name);
547
548         log_dbg("DM-UUID is %s", buf);
549         if (i >= buflen)
550                 log_err(NULL, _("DM-UUID for device %s was truncated.\n"), name);
551
552         return 1;
553 }
554
555 static int _dm_create_device(const char *name, const char *type,
556                              struct device *device, uint32_t flags,
557                              const char *uuid, uint64_t size,
558                              char *params, int reload)
559 {
560         struct dm_task *dmt = NULL;
561         struct dm_info dmi;
562         char dev_uuid[DM_UUID_LEN] = {0};
563         int r = -EINVAL;
564         uint32_t read_ahead = 0;
565         uint32_t cookie = 0;
566         uint16_t udev_flags = 0;
567
568         if (!params)
569                 return -EINVAL;
570
571         if (flags & CRYPT_ACTIVATE_PRIVATE)
572                 udev_flags = CRYPT_TEMP_UDEV_FLAGS;
573
574         /* All devices must have DM_UUID, only resize on old device is exception */
575         if (reload) {
576                 if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
577                         goto out_no_removal;
578
579                 if (!dm_task_set_name(dmt, name))
580                         goto out_no_removal;
581         } else {
582                 if (!dm_prepare_uuid(name, type, uuid, dev_uuid, sizeof(dev_uuid)))
583                         goto out_no_removal;
584
585                 if (!(dmt = dm_task_create(DM_DEVICE_CREATE)))
586                         goto out_no_removal;
587
588                 if (!dm_task_set_name(dmt, name))
589                         goto out_no_removal;
590
591                 if (!dm_task_set_uuid(dmt, dev_uuid))
592                         goto out_no_removal;
593
594                 if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
595                         goto out_no_removal;
596         }
597
598         if ((dm_flags() & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
599                 goto out_no_removal;
600         if ((flags & CRYPT_ACTIVATE_READONLY) && !dm_task_set_ro(dmt))
601                 goto out_no_removal;
602
603         if (!dm_task_add_target(dmt, 0, size,
604                 !strcmp("VERITY", type) ? DM_VERITY_TARGET : DM_CRYPT_TARGET, params))
605                 goto out_no_removal;
606
607 #ifdef DM_READ_AHEAD_MINIMUM_FLAG
608         if (device_read_ahead(device, &read_ahead) &&
609             !dm_task_set_read_ahead(dmt, read_ahead, DM_READ_AHEAD_MINIMUM_FLAG))
610                 goto out_no_removal;
611 #endif
612
613         if (!dm_task_run(dmt))
614                 goto out_no_removal;
615
616         if (reload) {
617                 dm_task_destroy(dmt);
618                 if (!(dmt = dm_task_create(DM_DEVICE_RESUME)))
619                         goto out;
620                 if (!dm_task_set_name(dmt, name))
621                         goto out;
622                 if (uuid && !dm_task_set_uuid(dmt, dev_uuid))
623                         goto out;
624                 if (_dm_use_udev() && !_dm_task_set_cookie(dmt, &cookie, udev_flags))
625                         goto out;
626                 if (!dm_task_run(dmt))
627                         goto out;
628         }
629
630         if (!dm_task_get_info(dmt, &dmi))
631                 goto out;
632
633         r = 0;
634 out:
635         if (_dm_use_udev()) {
636                 (void)_dm_udev_wait(cookie);
637                 cookie = 0;
638         }
639
640         if (r < 0 && !reload)
641                 _dm_simple(DM_DEVICE_REMOVE, name, 1);
642
643 out_no_removal:
644         if (cookie && _dm_use_udev())
645                 (void)_dm_udev_wait(cookie);
646
647         if (dmt)
648                 dm_task_destroy(dmt);
649
650         dm_task_update_nodes();
651
652         /* If code just loaded target module, update versions */
653         _dm_check_versions();
654
655         return r;
656 }
657
658 int dm_create_device(struct crypt_device *cd, const char *name,
659                      const char *type,
660                      struct crypt_dm_active_device *dmd,
661                      int reload)
662 {
663         char *table_params = NULL;
664         uint32_t dmd_flags;
665         int r;
666
667         if (!type)
668                 return -EINVAL;
669
670         if (dm_init_context(cd))
671                 return -ENOTSUP;
672
673         dmd_flags = dmd->flags;
674
675         if (dmd->target == DM_CRYPT)
676                 table_params = get_dm_crypt_params(dmd, dmd_flags);
677         else if (dmd->target == DM_VERITY)
678                 table_params = get_dm_verity_params(dmd->u.verity.vp, dmd);
679
680         r = _dm_create_device(name, type, dmd->data_device, dmd_flags,
681                               dmd->uuid, dmd->size, table_params, reload);
682
683         /* If discard not supported try to load without discard */
684         if (!reload && r && dmd->target == DM_CRYPT &&
685             (dmd->flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) &&
686             !(dm_flags() & DM_DISCARDS_SUPPORTED)) {
687                 log_dbg("Discard/TRIM is not supported, retrying activation.");
688                 dmd_flags = dmd_flags & ~CRYPT_ACTIVATE_ALLOW_DISCARDS;
689                 crypt_safe_free(table_params);
690                 table_params = get_dm_crypt_params(dmd, dmd_flags);
691                 r = _dm_create_device(name, type, dmd->data_device, dmd_flags,
692                                       dmd->uuid, dmd->size, table_params, reload);
693         }
694
695         if (r == -EINVAL &&
696             dmd_flags & (CRYPT_ACTIVATE_SAME_CPU_CRYPT|CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) &&
697             !(dm_flags() & (DM_SAME_CPU_CRYPT_SUPPORTED|DM_SUBMIT_FROM_CRYPT_CPUS_SUPPORTED)))
698                 log_err(cd, _("Requested dmcrypt performance options are not supported.\n"));
699
700         crypt_safe_free(table_params);
701         dm_exit_context();
702         return r;
703 }
704
705 static int dm_status_dmi(const char *name, struct dm_info *dmi,
706                           const char *target, char **status_line)
707 {
708         struct dm_task *dmt;
709         uint64_t start, length;
710         char *target_type, *params = NULL;
711         void *next = NULL;
712         int r = -EINVAL;
713
714         if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
715                 goto out;
716
717         if (!dm_task_set_name(dmt, name))
718                 goto out;
719
720         if (!dm_task_run(dmt))
721                 goto out;
722
723         if (!dm_task_get_info(dmt, dmi))
724                 goto out;
725
726         if (!dmi->exists) {
727                 r = -ENODEV;
728                 goto out;
729         }
730
731         next = dm_get_next_target(dmt, next, &start, &length,
732                                   &target_type, &params);
733
734         if (!target_type || start != 0 || next)
735                 goto out;
736
737         if (target && strcmp(target_type, target))
738                 goto out;
739
740         /* for target == NULL check all supported */
741         if (!target && (strcmp(target_type, DM_CRYPT_TARGET) &&
742                         strcmp(target_type, DM_VERITY_TARGET)))
743                 goto out;
744         r = 0;
745 out:
746         if (!r && status_line && !(*status_line = strdup(params)))
747                 r = -ENOMEM;
748
749         if (dmt)
750                 dm_task_destroy(dmt);
751
752         return r;
753 }
754
755 int dm_status_device(struct crypt_device *cd, const char *name)
756 {
757         int r;
758         struct dm_info dmi;
759         struct stat st;
760
761         /* libdevmapper is too clever and handles
762          * path argument differenly with error.
763          * Fail early here if parameter is non-existent path.
764          */
765         if (strchr(name, '/') && stat(name, &st) < 0)
766                 return -ENODEV;
767
768         if (dm_init_context(cd))
769                 return -ENOTSUP;
770         r = dm_status_dmi(name, &dmi, NULL, NULL);
771         dm_exit_context();
772         if (r < 0)
773                 return r;
774
775         return (dmi.open_count > 0);
776 }
777
778 int dm_status_suspended(struct crypt_device *cd, const char *name)
779 {
780         int r;
781         struct dm_info dmi;
782
783         if (dm_init_context(cd))
784                 return -ENOTSUP;
785         r = dm_status_dmi(name, &dmi, DM_CRYPT_TARGET, NULL);
786         dm_exit_context();
787         if (r < 0)
788                 return r;
789
790         return dmi.suspended ? 1 : 0;
791 }
792
793 static int _dm_status_verity_ok(const char *name)
794 {
795         int r;
796         struct dm_info dmi;
797         char *status_line = NULL;
798
799         r = dm_status_dmi(name, &dmi, DM_VERITY_TARGET, &status_line);
800         if (r < 0 || !status_line) {
801                 free(status_line);
802                 return r;
803         }
804
805         log_dbg("Verity volume %s status is %s.", name, status_line ?: "");
806         r = status_line[0] == 'V' ? 1 : 0;
807         free(status_line);
808
809         return r;
810 }
811
812 int dm_status_verity_ok(struct crypt_device *cd, const char *name)
813 {
814         int r;
815
816         if (dm_init_context(cd))
817                 return -ENOTSUP;
818         r = _dm_status_verity_ok(name);
819         dm_exit_context();
820         return r;
821 }
822
823 /* FIXME use hex wrapper, user val wrappers for line parsing */
824 static int _dm_query_crypt(uint32_t get_flags,
825                            struct dm_info *dmi,
826                            char *params,
827                            struct crypt_dm_active_device *dmd)
828 {
829         uint64_t val64;
830         char *rcipher, *key_, *rdevice, *endp, buffer[3], *arg;
831         unsigned int i;
832         int r;
833
834         memset(dmd, 0, sizeof(*dmd));
835         dmd->target = DM_CRYPT;
836
837         rcipher = strsep(&params, " ");
838         /* cipher */
839         if (get_flags & DM_ACTIVE_CRYPT_CIPHER)
840                 dmd->u.crypt.cipher = strdup(rcipher);
841
842         /* skip */
843         key_ = strsep(&params, " ");
844         if (!params)
845                 return -EINVAL;
846         val64 = strtoull(params, &params, 10);
847         if (*params != ' ')
848                 return -EINVAL;
849         params++;
850
851         dmd->u.crypt.iv_offset = val64;
852
853         /* device */
854         rdevice = strsep(&params, " ");
855         if (get_flags & DM_ACTIVE_DEVICE) {
856                 arg = crypt_lookup_dev(rdevice);
857                 r = device_alloc(&dmd->data_device, arg);
858                 free(arg);
859                 if (r < 0 && r != -ENOTBLK)
860                         return r;
861         }
862
863         /*offset */
864         if (!params)
865                 return -EINVAL;
866         val64 = strtoull(params, &params, 10);
867         dmd->u.crypt.offset = val64;
868
869         /* Features section, available since crypt target version 1.11 */
870         if (*params) {
871                 if (*params != ' ')
872                         return -EINVAL;
873                 params++;
874
875                 /* Number of arguments */
876                 val64 = strtoull(params, &params, 10);
877                 if (*params != ' ')
878                         return -EINVAL;
879                 params++;
880
881                 for (i = 0; i < val64; i++) {
882                         if (!params)
883                                 return -EINVAL;
884                         arg = strsep(&params, " ");
885                         if (!strcasecmp(arg, "allow_discards"))
886                                 dmd->flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
887                         else if (!strcasecmp(arg, "same_cpu_crypt"))
888                                 dmd->flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
889                         else if (!strcasecmp(arg, "submit_from_crypt_cpus"))
890                                 dmd->flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
891                         else /* unknown option */
892                                 return -EINVAL;
893                 }
894
895                 /* All parameters shold be processed */
896                 if (params)
897                         return -EINVAL;
898         }
899
900         /* Never allow to return empty key */
901         if ((get_flags & DM_ACTIVE_CRYPT_KEY) && dmi->suspended) {
902                 log_dbg("Cannot read volume key while suspended.");
903                 return -EINVAL;
904         }
905
906         if (get_flags & DM_ACTIVE_CRYPT_KEYSIZE) {
907                 dmd->u.crypt.vk = crypt_alloc_volume_key(strlen(key_) / 2, NULL);
908                 if (!dmd->u.crypt.vk)
909                         return -ENOMEM;
910
911                 if (get_flags & DM_ACTIVE_CRYPT_KEY) {
912                         buffer[2] = '\0';
913                         for(i = 0; i < dmd->u.crypt.vk->keylength; i++) {
914                                 memcpy(buffer, &key_[i * 2], 2);
915                                 dmd->u.crypt.vk->key[i] = strtoul(buffer, &endp, 16);
916                                 if (endp != &buffer[2]) {
917                                         crypt_free_volume_key(dmd->u.crypt.vk);
918                                         dmd->u.crypt.vk = NULL;
919                                         return -EINVAL;
920                                 }
921                         }
922                 }
923         }
924         memset(key_, 0, strlen(key_));
925
926         return 0;
927 }
928
929 static int _dm_query_verity(uint32_t get_flags,
930                              struct dm_info *dmi,
931                              char *params,
932                              struct crypt_dm_active_device *dmd)
933 {
934         struct crypt_params_verity *vp = NULL;
935         uint32_t val32;
936         uint64_t val64;
937         ssize_t len;
938         char *str, *str2;
939         int r;
940
941         if (get_flags & DM_ACTIVE_VERITY_PARAMS)
942                 vp = dmd->u.verity.vp;
943
944         memset(dmd, 0, sizeof(*dmd));
945
946         dmd->target = DM_VERITY;
947         dmd->u.verity.vp = vp;
948
949         /* version */
950         val32 = strtoul(params, &params, 10);
951         if (*params != ' ')
952                 return -EINVAL;
953         if (vp)
954                 vp->hash_type = val32;
955         params++;
956
957         /* data device */
958         str = strsep(&params, " ");
959         if (!params)
960                 return -EINVAL;
961         if (get_flags & DM_ACTIVE_DEVICE) {
962                 str2 = crypt_lookup_dev(str);
963                 r = device_alloc(&dmd->data_device, str2);
964                 free(str2);
965                 if (r < 0 && r != -ENOTBLK)
966                         return r;
967         }
968
969         /* hash device */
970         str = strsep(&params, " ");
971         if (!params)
972                 return -EINVAL;
973         if (get_flags & DM_ACTIVE_VERITY_HASH_DEVICE) {
974                 str2 = crypt_lookup_dev(str);
975                 r = device_alloc(&dmd->u.verity.hash_device, str2);
976                 free(str2);
977                 if (r < 0 && r != -ENOTBLK)
978                         return r;
979         }
980
981         /* data block size*/
982         val32 = strtoul(params, &params, 10);
983         if (*params != ' ')
984                 return -EINVAL;
985         if (vp)
986                 vp->data_block_size = val32;
987         params++;
988
989         /* hash block size */
990         val32 = strtoul(params, &params, 10);
991         if (*params != ' ')
992                 return -EINVAL;
993         if (vp)
994                 vp->hash_block_size = val32;
995         params++;
996
997         /* data blocks */
998         val64 = strtoull(params, &params, 10);
999         if (*params != ' ')
1000                 return -EINVAL;
1001         if (vp)
1002                 vp->data_size = val64;
1003         params++;
1004
1005         /* hash start */
1006         val64 = strtoull(params, &params, 10);
1007         if (*params != ' ')
1008                 return -EINVAL;
1009         dmd->u.verity.hash_offset = val64;
1010         params++;
1011
1012         /* hash algorithm */
1013         str = strsep(&params, " ");
1014         if (!params)
1015                 return -EINVAL;
1016         if (vp)
1017                 vp->hash_name = strdup(str);
1018
1019         /* root digest */
1020         str = strsep(&params, " ");
1021         if (!params)
1022                 return -EINVAL;
1023         len = crypt_hex_to_bytes(str, &str2, 0);
1024         if (len < 0)
1025                 return len;
1026         dmd->u.verity.root_hash_size = len;
1027         if (get_flags & DM_ACTIVE_VERITY_ROOT_HASH)
1028                 dmd->u.verity.root_hash = str2;
1029         else
1030                 free(str2);
1031
1032         /* salt */
1033         str = strsep(&params, " ");
1034         if (params)
1035                 return -EINVAL;
1036         if (vp) {
1037                 if (!strcmp(str, "-")) {
1038                         vp->salt_size = 0;
1039                         vp->salt = NULL;
1040                 } else {
1041                         len = crypt_hex_to_bytes(str, &str2, 0);
1042                         if (len < 0)
1043                                 return len;
1044                         vp->salt_size = len;
1045                         vp->salt = str2;
1046                 }
1047         }
1048
1049         return 0;
1050 }
1051
1052 int dm_query_device(struct crypt_device *cd, const char *name,
1053                     uint32_t get_flags, struct crypt_dm_active_device *dmd)
1054 {
1055         struct dm_task *dmt;
1056         struct dm_info dmi;
1057         uint64_t start, length;
1058         char *target_type, *params;
1059         const char *tmp_uuid;
1060         void *next = NULL;
1061         int r = -EINVAL;
1062
1063         if (dm_init_context(cd))
1064                 return -ENOTSUP;
1065         if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
1066                 goto out;
1067         if ((dm_flags() & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
1068                 goto out;
1069         if (!dm_task_set_name(dmt, name))
1070                 goto out;
1071         r = -ENODEV;
1072         if (!dm_task_run(dmt))
1073                 goto out;
1074
1075         r = -EINVAL;
1076         if (!dm_task_get_info(dmt, &dmi))
1077                 goto out;
1078
1079         if (!dmi.exists) {
1080                 r = -ENODEV;
1081                 goto out;
1082         }
1083
1084         next = dm_get_next_target(dmt, next, &start, &length,
1085                                   &target_type, &params);
1086
1087         if (!target_type || start != 0 || next)
1088                 goto out;
1089
1090         if (!strcmp(target_type, DM_CRYPT_TARGET)) {
1091                 r = _dm_query_crypt(get_flags, &dmi, params, dmd);
1092         } else if (!strcmp(target_type, DM_VERITY_TARGET)) {
1093                 r = _dm_query_verity(get_flags, &dmi, params, dmd);
1094                 if (r < 0)
1095                         goto out;
1096                 r = _dm_status_verity_ok(name);
1097                 if (r < 0)
1098                         goto out;
1099                 if (r == 0)
1100                         dmd->flags |= CRYPT_ACTIVATE_CORRUPTED;
1101                 r = 0;
1102         } else
1103                 r = -EINVAL;
1104
1105         if (r < 0)
1106                 goto out;
1107
1108         dmd->size = length;
1109
1110         if (dmi.read_only)
1111                 dmd->flags |= CRYPT_ACTIVATE_READONLY;
1112
1113         tmp_uuid = dm_task_get_uuid(dmt);
1114         if (!tmp_uuid)
1115                 dmd->flags |= CRYPT_ACTIVATE_NO_UUID;
1116         else if (get_flags & DM_ACTIVE_UUID) {
1117                 if (!strncmp(tmp_uuid, DM_UUID_PREFIX, DM_UUID_PREFIX_LEN))
1118                         dmd->uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
1119         }
1120
1121         r = (dmi.open_count > 0);
1122 out:
1123         if (dmt)
1124                 dm_task_destroy(dmt);
1125
1126         dm_exit_context();
1127         return r;
1128 }
1129
1130 static int _dm_message(const char *name, const char *msg)
1131 {
1132         int r = 0;
1133         struct dm_task *dmt;
1134
1135         if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
1136                 return 0;
1137
1138         if ((dm_flags() & DM_SECURE_SUPPORTED) && !dm_task_secure_data(dmt))
1139                 goto out;
1140
1141         if (name && !dm_task_set_name(dmt, name))
1142                 goto out;
1143
1144         if (!dm_task_set_sector(dmt, (uint64_t) 0))
1145                 goto out;
1146
1147         if (!dm_task_set_message(dmt, msg))
1148                 goto out;
1149
1150         r = dm_task_run(dmt);
1151
1152       out:
1153         dm_task_destroy(dmt);
1154         return r;
1155 }
1156
1157 int dm_suspend_and_wipe_key(struct crypt_device *cd, const char *name)
1158 {
1159         int r = -ENOTSUP;
1160
1161         if (dm_init_context(cd))
1162                 return -ENOTSUP;
1163
1164         if (!(_dm_crypt_flags & DM_KEY_WIPE_SUPPORTED))
1165                 goto out;
1166
1167         if (!_dm_simple(DM_DEVICE_SUSPEND, name, 0)) {
1168                 r = -EINVAL;
1169                 goto out;
1170         }
1171
1172         if (!_dm_message(name, "key wipe")) {
1173                 _dm_simple(DM_DEVICE_RESUME, name, 1);
1174                 r = -EINVAL;
1175                 goto out;
1176         }
1177         r = 0;
1178 out:
1179         dm_exit_context();
1180         return r;
1181 }
1182
1183 int dm_resume_and_reinstate_key(struct crypt_device *cd, const char *name,
1184                                 size_t key_size, const char *key)
1185 {
1186         int msg_size = key_size * 2 + 10; // key set <key>
1187         char *msg = NULL;
1188         int r = -ENOTSUP;
1189
1190         if (dm_init_context(cd))
1191                 return -ENOTSUP;
1192
1193         if (!(_dm_crypt_flags & DM_KEY_WIPE_SUPPORTED))
1194                 goto out;
1195
1196         msg = crypt_safe_alloc(msg_size);
1197         if (!msg) {
1198                 r = -ENOMEM;
1199                 goto out;
1200         }
1201
1202         strcpy(msg, "key set ");
1203         hex_key(&msg[8], key_size, key);
1204
1205         if (!_dm_message(name, msg) ||
1206             !_dm_simple(DM_DEVICE_RESUME, name, 1)) {
1207                 r = -EINVAL;
1208                 goto out;
1209         }
1210         r = 0;
1211 out:
1212         crypt_safe_free(msg);
1213         dm_exit_context();
1214         return r;
1215 }
1216
1217 const char *dm_get_dir(void)
1218 {
1219         return dm_dir();
1220 }
1221
1222 int dm_is_dm_device(int major, int minor)
1223 {
1224         return dm_is_dm_major((uint32_t)major);
1225 }
1226
1227 int dm_is_dm_kernel_name(const char *name)
1228 {
1229         return strncmp(name, "dm-", 3) ? 0 : 1;
1230 }