1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2016 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #if HAVE_LIBCRYPTSETUP
22 #include <libcryptsetup.h>
24 #define CRYPT_LUKS NULL
27 #include <sys/mount.h>
29 #include "architecture.h"
30 #include "ask-password-api.h"
31 #include "blkid-util.h"
32 #include "dissect-image.h"
37 #include "hexdecoct.h"
38 #include "linux-3.13/dm-ioctl.h"
39 #include "mount-util.h"
40 #include "path-util.h"
41 #include "stat-util.h"
42 #include "stdio-util.h"
43 #include "string-table.h"
44 #include "string-util.h"
46 #include "udev-util.h"
47 #include "xattr-util.h"
49 _unused_
static int probe_filesystem(const char *node
, char **ret_fstype
) {
51 _cleanup_blkid_free_probe_ blkid_probe b
= NULL
;
55 b
= blkid_new_probe_from_filename(node
);
59 blkid_probe_enable_superblocks(b
, 1);
60 blkid_probe_set_superblocks_flags(b
, BLKID_SUBLKS_TYPE
);
63 r
= blkid_do_safeprobe(b
);
64 if (IN_SET(r
, -2, 1)) {
65 log_debug("Failed to identify any partition type on partition %s", node
);
69 return -errno
?: -EIO
;
71 (void) blkid_probe_lookup_value(b
, "TYPE", &fstype
, NULL
);
92 int dissect_image(int fd
, const void *root_hash
, size_t root_hash_size
, DissectImageFlags flags
, DissectedImage
**ret
) {
95 sd_id128_t root_uuid
= SD_ID128_NULL
, verity_uuid
= SD_ID128_NULL
;
96 _cleanup_udev_enumerate_unref_
struct udev_enumerate
*e
= NULL
;
97 bool is_gpt
, is_mbr
, generic_rw
, multiple_generic
= false;
98 _cleanup_udev_device_unref_
struct udev_device
*d
= NULL
;
99 _cleanup_(dissected_image_unrefp
) DissectedImage
*m
= NULL
;
100 _cleanup_blkid_free_probe_ blkid_probe b
= NULL
;
101 _cleanup_udev_unref_
struct udev
*udev
= NULL
;
102 _cleanup_free_
char *generic_node
= NULL
;
103 sd_id128_t generic_uuid
= SD_ID128_NULL
;
104 const char *pttype
= NULL
;
105 struct udev_list_entry
*first
, *item
;
113 assert(root_hash
|| root_hash_size
== 0);
115 /* Probes a disk image, and returns information about what it found in *ret.
117 * Returns -ENOPKG if no suitable partition table or file system could be found.
118 * Returns -EADDRNOTAVAIL if a root hash was specified but no matching root/verity partitions found. */
121 /* If a root hash is supplied, then we use the root partition that has a UUID that match the first
122 * 128bit of the root hash. And we use the verity partition that has a UUID that match the final
125 if (root_hash_size
< sizeof(sd_id128_t
))
128 memcpy(&root_uuid
, root_hash
, sizeof(sd_id128_t
));
129 memcpy(&verity_uuid
, (const uint8_t*) root_hash
+ root_hash_size
- sizeof(sd_id128_t
), sizeof(sd_id128_t
));
131 if (sd_id128_is_null(root_uuid
))
133 if (sd_id128_is_null(verity_uuid
))
137 if (fstat(fd
, &st
) < 0)
140 if (!S_ISBLK(st
.st_mode
))
143 b
= blkid_new_probe();
148 r
= blkid_probe_set_device(b
, fd
, 0, 0);
150 return -errno
?: -ENOMEM
;
152 if ((flags
& DISSECT_IMAGE_GPT_ONLY
) == 0) {
153 /* Look for file system superblocks, unless we only shall look for GPT partition tables */
154 blkid_probe_enable_superblocks(b
, 1);
155 blkid_probe_set_superblocks_flags(b
, BLKID_SUBLKS_TYPE
|BLKID_SUBLKS_USAGE
);
158 blkid_probe_enable_partitions(b
, 1);
159 blkid_probe_set_partitions_flags(b
, BLKID_PARTS_ENTRY_DETAILS
);
162 r
= blkid_do_safeprobe(b
);
163 if (IN_SET(r
, -2, 1)) {
164 log_debug("Failed to identify any partition table.");
168 return -errno
?: -EIO
;
170 m
= new0(DissectedImage
, 1);
174 if (!(flags
& DISSECT_IMAGE_GPT_ONLY
) &&
175 (flags
& DISSECT_IMAGE_REQUIRE_ROOT
)) {
176 const char *usage
= NULL
;
178 (void) blkid_probe_lookup_value(b
, "USAGE", &usage
, NULL
);
179 if (STRPTR_IN_SET(usage
, "filesystem", "crypto")) {
180 _cleanup_free_
char *t
= NULL
, *n
= NULL
;
181 const char *fstype
= NULL
;
183 /* OK, we have found a file system, that's our root partition then. */
184 (void) blkid_probe_lookup_value(b
, "TYPE", &fstype
, NULL
);
192 if (asprintf(&n
, "/dev/block/%u:%u", major(st
.st_rdev
), minor(st
.st_rdev
)) < 0)
195 m
->partitions
[PARTITION_ROOT
] = (DissectedPartition
) {
199 .architecture
= _ARCHITECTURE_INVALID
,
206 m
->encrypted
= streq(fstype
, "crypto_LUKS");
215 (void) blkid_probe_lookup_value(b
, "PTTYPE", &pttype
, NULL
);
219 is_gpt
= streq_ptr(pttype
, "gpt");
220 is_mbr
= streq_ptr(pttype
, "dos");
222 if (!is_gpt
&& ((flags
& DISSECT_IMAGE_GPT_ONLY
) || !is_mbr
))
226 pl
= blkid_probe_get_partitions(b
);
228 return -errno
?: -ENOMEM
;
234 d
= udev_device_new_from_devnum(udev
, 'b', st
.st_rdev
);
242 log_debug("Kernel partitions never appeared.");
246 e
= udev_enumerate_new(udev
);
250 r
= udev_enumerate_add_match_parent(e
, d
);
254 r
= udev_enumerate_scan_devices(e
);
258 /* Count the partitions enumerated by the kernel */
260 first
= udev_enumerate_get_list_entry(e
);
261 udev_list_entry_foreach(item
, first
)
264 /* Count the partitions enumerated by blkid */
265 z
= blkid_partlist_numof_partitions(pl
);
269 log_debug("blkid and kernel partition list do not match.");
275 /* The kernel has probed fewer partitions than blkid? Maybe the kernel prober is still running
276 * or it got EBUSY because udev already opened the device. Let's reprobe the device, which is a
277 * synchronous call that waits until probing is complete. */
283 if (ioctl(fd
, BLKRRPART
, 0) < 0) {
287 struct loop_info64 info
;
289 /* If we are running on a loop device that has partition scanning off,
290 * return an explicit recognizable error about this, so that callers
291 * can generate a proper message explaining the situation. */
293 if (ioctl(fd
, LOOP_GET_STATUS64
, &info
) >= 0 && (info
.lo_flags
& LO_FLAGS_PARTSCAN
) == 0) {
294 log_debug("Device is loop device and partition scanning is off!");
295 return -EPROTONOSUPPORT
;
303 /* If something else has the device open, such as an udev rule, the ioctl will return
304 * EBUSY. Since there's no way to wait until it isn't busy anymore, let's just wait a
305 * bit, and try again.
307 * This is really something they should fix in the kernel! */
309 (void) usleep(50 * USEC_PER_MSEC
);
313 e
= udev_enumerate_unref(e
);
316 first
= udev_enumerate_get_list_entry(e
);
317 udev_list_entry_foreach(item
, first
) {
318 _cleanup_udev_device_unref_
struct udev_device
*q
;
319 unsigned long long pflags
;
321 const char *node
, *sysname
;
325 q
= udev_device_new_from_syspath(udev
, udev_list_entry_get_name(item
));
329 qn
= udev_device_get_devnum(q
);
333 if (st
.st_rdev
== qn
)
336 /* Filter out weird MMC RPMB partitions, which cannot reasonably be read, see
337 * https://github.com/systemd/systemd/issues/5806 */
338 sysname
= udev_device_get_sysname(q
);
339 if (sysname
&& startswith(sysname
, "mmcblk") && endswith(sysname
, "rpmb"))
342 node
= udev_device_get_devnode(q
);
346 pp
= blkid_partlist_devno_to_partition(pl
, qn
);
350 pflags
= blkid_partition_get_flags(pp
);
352 nr
= blkid_partition_get_partno(pp
);
357 int designator
= _PARTITION_DESIGNATOR_INVALID
, architecture
= _ARCHITECTURE_INVALID
;
358 const char *stype
, *sid
, *fstype
= NULL
;
359 sd_id128_t type_id
, id
;
362 sid
= blkid_partition_get_uuid(pp
);
365 if (sd_id128_from_string(sid
, &id
) < 0)
368 stype
= blkid_partition_get_type_string(pp
);
371 if (sd_id128_from_string(stype
, &type_id
) < 0)
374 if (sd_id128_equal(type_id
, GPT_HOME
)) {
376 if (pflags
& GPT_FLAG_NO_AUTO
)
379 designator
= PARTITION_HOME
;
380 rw
= !(pflags
& GPT_FLAG_READ_ONLY
);
381 } else if (sd_id128_equal(type_id
, GPT_SRV
)) {
383 if (pflags
& GPT_FLAG_NO_AUTO
)
386 designator
= PARTITION_SRV
;
387 rw
= !(pflags
& GPT_FLAG_READ_ONLY
);
388 } else if (sd_id128_equal(type_id
, GPT_ESP
)) {
390 /* Note that we don't check the GPT_FLAG_NO_AUTO flag for the ESP, as it is not defined
391 * there. We instead check the GPT_FLAG_NO_BLOCK_IO_PROTOCOL, as recommended by the
392 * UEFI spec (See "12.3.3 Number and Location of System Partitions"). */
394 if (pflags
& GPT_FLAG_NO_BLOCK_IO_PROTOCOL
)
397 designator
= PARTITION_ESP
;
400 #ifdef GPT_ROOT_NATIVE
401 else if (sd_id128_equal(type_id
, GPT_ROOT_NATIVE
)) {
403 if (pflags
& GPT_FLAG_NO_AUTO
)
406 /* If a root ID is specified, ignore everything but the root id */
407 if (!sd_id128_is_null(root_uuid
) && !sd_id128_equal(root_uuid
, id
))
410 designator
= PARTITION_ROOT
;
411 architecture
= native_architecture();
412 rw
= !(pflags
& GPT_FLAG_READ_ONLY
);
413 } else if (sd_id128_equal(type_id
, GPT_ROOT_NATIVE_VERITY
)) {
415 if (pflags
& GPT_FLAG_NO_AUTO
)
418 m
->can_verity
= true;
420 /* Ignore verity unless a root hash is specified */
421 if (sd_id128_is_null(verity_uuid
) || !sd_id128_equal(verity_uuid
, id
))
424 designator
= PARTITION_ROOT_VERITY
;
425 fstype
= "DM_verity_hash";
426 architecture
= native_architecture();
430 #ifdef GPT_ROOT_SECONDARY
431 else if (sd_id128_equal(type_id
, GPT_ROOT_SECONDARY
)) {
433 if (pflags
& GPT_FLAG_NO_AUTO
)
436 /* If a root ID is specified, ignore everything but the root id */
437 if (!sd_id128_is_null(root_uuid
) && !sd_id128_equal(root_uuid
, id
))
440 designator
= PARTITION_ROOT_SECONDARY
;
441 architecture
= SECONDARY_ARCHITECTURE
;
442 rw
= !(pflags
& GPT_FLAG_READ_ONLY
);
443 } else if (sd_id128_equal(type_id
, GPT_ROOT_SECONDARY_VERITY
)) {
445 if (pflags
& GPT_FLAG_NO_AUTO
)
448 m
->can_verity
= true;
450 /* Ignore verity unless root has is specified */
451 if (sd_id128_is_null(verity_uuid
) || !sd_id128_equal(verity_uuid
, id
))
454 designator
= PARTITION_ROOT_SECONDARY_VERITY
;
455 fstype
= "DM_verity_hash";
456 architecture
= SECONDARY_ARCHITECTURE
;
460 else if (sd_id128_equal(type_id
, GPT_SWAP
)) {
462 if (pflags
& GPT_FLAG_NO_AUTO
)
465 designator
= PARTITION_SWAP
;
467 } else if (sd_id128_equal(type_id
, GPT_LINUX_GENERIC
)) {
469 if (pflags
& GPT_FLAG_NO_AUTO
)
473 multiple_generic
= true;
476 generic_rw
= !(pflags
& GPT_FLAG_READ_ONLY
);
478 generic_node
= strdup(node
);
484 if (designator
!= _PARTITION_DESIGNATOR_INVALID
) {
485 _cleanup_free_
char *t
= NULL
, *n
= NULL
;
488 if (m
->partitions
[designator
].found
)
501 m
->partitions
[designator
] = (DissectedPartition
) {
505 .architecture
= architecture
,
516 if (pflags
!= 0x80) /* Bootable flag */
519 if (blkid_partition_get_type(pp
) != 0x83) /* Linux partition */
523 multiple_generic
= true;
527 generic_node
= strdup(node
);
534 if (!m
->partitions
[PARTITION_ROOT
].found
) {
535 /* No root partition found? Then let's see if ther's one for the secondary architecture. And if not
536 * either, then check if there's a single generic one, and use that. */
538 if (m
->partitions
[PARTITION_ROOT_VERITY
].found
)
539 return -EADDRNOTAVAIL
;
541 if (m
->partitions
[PARTITION_ROOT_SECONDARY
].found
) {
542 m
->partitions
[PARTITION_ROOT
] = m
->partitions
[PARTITION_ROOT_SECONDARY
];
543 zero(m
->partitions
[PARTITION_ROOT_SECONDARY
]);
545 m
->partitions
[PARTITION_ROOT_VERITY
] = m
->partitions
[PARTITION_ROOT_SECONDARY_VERITY
];
546 zero(m
->partitions
[PARTITION_ROOT_SECONDARY_VERITY
]);
548 } else if (flags
& DISSECT_IMAGE_REQUIRE_ROOT
) {
550 /* If the root has was set, then we won't fallback to a generic node, because the root hash
553 return -EADDRNOTAVAIL
;
555 /* If we didn't find a generic node, then we can't fix this up either */
559 /* If we didn't find a properly marked root partition, but we did find a single suitable
560 * generic Linux partition, then use this as root partition, if the caller asked for it. */
561 if (multiple_generic
)
564 m
->partitions
[PARTITION_ROOT
] = (DissectedPartition
) {
567 .partno
= generic_nr
,
568 .architecture
= _ARCHITECTURE_INVALID
,
569 .node
= generic_node
,
570 .uuid
= generic_uuid
,
578 if (!m
->partitions
[PARTITION_ROOT_VERITY
].found
|| !m
->partitions
[PARTITION_ROOT
].found
)
579 return -EADDRNOTAVAIL
;
581 /* If we found the primary root with the hash, then we definitely want to suppress any secondary root
582 * (which would be weird, after all the root hash should only be assigned to one pair of
584 m
->partitions
[PARTITION_ROOT_SECONDARY
].found
= false;
585 m
->partitions
[PARTITION_ROOT_SECONDARY_VERITY
].found
= false;
587 /* If we found a verity setup, then the root partition is necessarily read-only. */
588 m
->partitions
[PARTITION_ROOT
].rw
= false;
596 /* Fill in file system types if we don't know them yet. */
597 for (i
= 0; i
< _PARTITION_DESIGNATOR_MAX
; i
++) {
598 DissectedPartition
*p
= m
->partitions
+ i
;
603 if (!p
->fstype
&& p
->node
) {
604 r
= probe_filesystem(p
->node
, &p
->fstype
);
609 if (streq_ptr(p
->fstype
, "crypto_LUKS"))
612 if (p
->fstype
&& fstype_is_ro(p
->fstype
))
625 DissectedImage
* dissected_image_unref(DissectedImage
*m
) {
631 for (i
= 0; i
< _PARTITION_DESIGNATOR_MAX
; i
++) {
632 free(m
->partitions
[i
].fstype
);
633 free(m
->partitions
[i
].node
);
634 free(m
->partitions
[i
].decrypted_fstype
);
635 free(m
->partitions
[i
].decrypted_node
);
642 static int is_loop_device(const char *path
) {
643 char s
[strlen("/sys/dev/block/") + DECIMAL_STR_MAX(dev_t
) + 1 + DECIMAL_STR_MAX(dev_t
) + strlen("/../loop/")];
648 if (stat(path
, &st
) < 0)
651 if (!S_ISBLK(st
.st_mode
))
654 xsprintf(s
, "/sys/dev/block/%u:%u/loop/", major(st
.st_rdev
), minor(st
.st_rdev
));
655 if (access(s
, F_OK
) < 0) {
659 /* The device itself isn't a loop device, but maybe it's a partition and its parent is? */
660 xsprintf(s
, "/sys/dev/block/%u:%u/../loop/", major(st
.st_rdev
), minor(st
.st_rdev
));
661 if (access(s
, F_OK
) < 0)
662 return errno
== ENOENT
? false : -errno
;
668 static int mount_partition(
669 DissectedPartition
*m
,
671 const char *directory
,
672 DissectImageFlags flags
) {
674 const char *p
, *options
= NULL
, *node
, *fstype
;
675 _cleanup_free_
char *chased
= NULL
;
682 node
= m
->decrypted_node
?: m
->node
;
683 fstype
= m
->decrypted_fstype
?: m
->fstype
;
685 if (!m
->found
|| !node
|| !fstype
)
688 /* Stacked encryption? Yuck */
689 if (streq_ptr(fstype
, "crypto_LUKS"))
692 rw
= m
->rw
&& !(flags
& DISSECT_IMAGE_READ_ONLY
);
695 r
= chase_symlinks(directory
, where
, CHASE_PREFIX_ROOT
, &chased
);
703 /* If requested, turn on discard support. */
704 if (fstype_can_discard(fstype
) &&
705 ((flags
& DISSECT_IMAGE_DISCARD
) ||
706 ((flags
& DISSECT_IMAGE_DISCARD_ON_LOOP
) && is_loop_device(m
->node
))))
709 return mount_verbose(LOG_DEBUG
, node
, p
, fstype
, MS_NODEV
|(rw
? 0 : MS_RDONLY
), options
);
712 int dissected_image_mount(DissectedImage
*m
, const char *where
, DissectImageFlags flags
) {
718 if (!m
->partitions
[PARTITION_ROOT
].found
)
721 r
= mount_partition(m
->partitions
+ PARTITION_ROOT
, where
, NULL
, flags
);
725 r
= mount_partition(m
->partitions
+ PARTITION_HOME
, where
, "/home", flags
);
729 r
= mount_partition(m
->partitions
+ PARTITION_SRV
, where
, "/srv", flags
);
733 if (m
->partitions
[PARTITION_ESP
].found
) {
736 /* Mount the ESP to /efi if it exists and is empty. If it doesn't exist, use /boot instead. */
738 FOREACH_STRING(mp
, "/efi", "/boot") {
739 _cleanup_free_
char *p
= NULL
;
741 r
= chase_symlinks(mp
, where
, CHASE_PREFIX_ROOT
, &p
);
747 r
= mount_partition(m
->partitions
+ PARTITION_ESP
, where
, mp
, flags
);
757 #if HAVE_LIBCRYPTSETUP
758 typedef struct DecryptedPartition
{
759 struct crypt_device
*device
;
762 } DecryptedPartition
;
764 struct DecryptedImage
{
765 DecryptedPartition
*decrypted
;
771 DecryptedImage
* decrypted_image_unref(DecryptedImage
* d
) {
772 #if HAVE_LIBCRYPTSETUP
779 for (i
= 0; i
< d
->n_decrypted
; i
++) {
780 DecryptedPartition
*p
= d
->decrypted
+ i
;
782 if (p
->device
&& p
->name
&& !p
->relinquished
) {
783 r
= crypt_deactivate(p
->device
, p
->name
);
785 log_debug_errno(r
, "Failed to deactivate encrypted partition %s", p
->name
);
789 crypt_free(p
->device
);
798 #if HAVE_LIBCRYPTSETUP
800 static int make_dm_name_and_node(const void *original_node
, const char *suffix
, char **ret_name
, char **ret_node
) {
801 _cleanup_free_
char *name
= NULL
, *node
= NULL
;
804 assert(original_node
);
809 base
= strrchr(original_node
, '/');
816 name
= strjoin(base
, suffix
);
819 if (!filename_is_valid(name
))
822 node
= strjoin(crypt_get_dir(), "/", name
);
833 static int decrypt_partition(
834 DissectedPartition
*m
,
835 const char *passphrase
,
836 DissectImageFlags flags
,
839 _cleanup_free_
char *node
= NULL
, *name
= NULL
;
840 struct crypt_device
*cd
;
846 if (!m
->found
|| !m
->node
|| !m
->fstype
)
849 if (!streq(m
->fstype
, "crypto_LUKS"))
852 r
= make_dm_name_and_node(m
->node
, "-decrypted", &name
, &node
);
856 if (!GREEDY_REALLOC0(d
->decrypted
, d
->n_allocated
, d
->n_decrypted
+ 1))
859 r
= crypt_init(&cd
, m
->node
);
861 return log_debug_errno(r
, "Failed to initialize dm-crypt: %m");
863 r
= crypt_load(cd
, CRYPT_LUKS
, NULL
);
865 log_debug_errno(r
, "Failed to load LUKS metadata: %m");
869 r
= crypt_activate_by_passphrase(cd
, name
, CRYPT_ANY_SLOT
, passphrase
, strlen(passphrase
),
870 ((flags
& DISSECT_IMAGE_READ_ONLY
) ? CRYPT_ACTIVATE_READONLY
: 0) |
871 ((flags
& DISSECT_IMAGE_DISCARD_ON_CRYPTO
) ? CRYPT_ACTIVATE_ALLOW_DISCARDS
: 0));
873 log_debug_errno(r
, "Failed to activate LUKS device: %m");
881 d
->decrypted
[d
->n_decrypted
].name
= name
;
884 d
->decrypted
[d
->n_decrypted
].device
= cd
;
887 m
->decrypted_node
= node
;
897 static int verity_partition(
898 DissectedPartition
*m
,
899 DissectedPartition
*v
,
900 const void *root_hash
,
901 size_t root_hash_size
,
902 DissectImageFlags flags
,
905 _cleanup_free_
char *node
= NULL
, *name
= NULL
;
906 struct crypt_device
*cd
;
915 if (!m
->found
|| !m
->node
|| !m
->fstype
)
917 if (!v
->found
|| !v
->node
|| !v
->fstype
)
920 if (!streq(v
->fstype
, "DM_verity_hash"))
923 r
= make_dm_name_and_node(m
->node
, "-verity", &name
, &node
);
927 if (!GREEDY_REALLOC0(d
->decrypted
, d
->n_allocated
, d
->n_decrypted
+ 1))
930 r
= crypt_init(&cd
, v
->node
);
934 r
= crypt_load(cd
, CRYPT_VERITY
, NULL
);
938 r
= crypt_set_data_device(cd
, m
->node
);
942 r
= crypt_activate_by_volume_key(cd
, name
, root_hash
, root_hash_size
, CRYPT_ACTIVATE_READONLY
);
946 d
->decrypted
[d
->n_decrypted
].name
= name
;
949 d
->decrypted
[d
->n_decrypted
].device
= cd
;
952 m
->decrypted_node
= node
;
963 int dissected_image_decrypt(
965 const char *passphrase
,
966 const void *root_hash
,
967 size_t root_hash_size
,
968 DissectImageFlags flags
,
969 DecryptedImage
**ret
) {
971 _cleanup_(decrypted_image_unrefp
) DecryptedImage
*d
= NULL
;
972 #if HAVE_LIBCRYPTSETUP
978 assert(root_hash
|| root_hash_size
== 0);
982 * = 0 → There was nothing to decrypt
983 * > 0 → Decrypted successfully
984 * -ENOKEY → There's something to decrypt but no key was supplied
985 * -EKEYREJECTED → Passed key was not correct
988 if (root_hash
&& root_hash_size
< sizeof(sd_id128_t
))
991 if (!m
->encrypted
&& !m
->verity
) {
996 #if HAVE_LIBCRYPTSETUP
997 if (m
->encrypted
&& !passphrase
)
1000 d
= new0(DecryptedImage
, 1);
1004 for (i
= 0; i
< _PARTITION_DESIGNATOR_MAX
; i
++) {
1005 DissectedPartition
*p
= m
->partitions
+ i
;
1011 r
= decrypt_partition(p
, passphrase
, flags
, d
);
1015 k
= PARTITION_VERITY_OF(i
);
1017 r
= verity_partition(p
, m
->partitions
+ k
, root_hash
, root_hash_size
, flags
, d
);
1022 if (!p
->decrypted_fstype
&& p
->decrypted_node
) {
1023 r
= probe_filesystem(p
->decrypted_node
, &p
->decrypted_fstype
);
1038 int dissected_image_decrypt_interactively(
1040 const char *passphrase
,
1041 const void *root_hash
,
1042 size_t root_hash_size
,
1043 DissectImageFlags flags
,
1044 DecryptedImage
**ret
) {
1046 _cleanup_strv_free_erase_
char **z
= NULL
;
1053 r
= dissected_image_decrypt(m
, passphrase
, root_hash
, root_hash_size
, flags
, ret
);
1056 if (r
== -EKEYREJECTED
)
1057 log_error_errno(r
, "Incorrect passphrase, try again!");
1058 else if (r
!= -ENOKEY
) {
1059 log_error_errno(r
, "Failed to decrypt image: %m");
1064 log_error("Too many retries.");
1065 return -EKEYREJECTED
;
1070 r
= ask_password_auto("Please enter image passphrase!", NULL
, "dissect", "dissect", USEC_INFINITY
, 0, &z
);
1072 return log_error_errno(r
, "Failed to query for passphrase: %m");
1078 #if HAVE_LIBCRYPTSETUP
1079 static int deferred_remove(DecryptedPartition
*p
) {
1081 struct dm_ioctl dm
= {
1085 DM_VERSION_PATCHLEVEL
1087 .data_size
= sizeof(dm
),
1088 .flags
= DM_DEFERRED_REMOVE
,
1091 _cleanup_close_
int fd
= -1;
1095 /* Unfortunately, libcryptsetup doesn't provide a proper API for this, hence call the ioctl() directly. */
1097 fd
= open("/dev/mapper/control", O_RDWR
|O_CLOEXEC
);
1101 strncpy(dm
.name
, p
->name
, sizeof(dm
.name
));
1103 if (ioctl(fd
, DM_DEV_REMOVE
, &dm
))
1110 int decrypted_image_relinquish(DecryptedImage
*d
) {
1112 #if HAVE_LIBCRYPTSETUP
1119 /* Turns on automatic removal after the last use ended for all DM devices of this image, and sets a boolean so
1120 * that we don't clean it up ourselves either anymore */
1122 #if HAVE_LIBCRYPTSETUP
1123 for (i
= 0; i
< d
->n_decrypted
; i
++) {
1124 DecryptedPartition
*p
= d
->decrypted
+ i
;
1126 if (p
->relinquished
)
1129 r
= deferred_remove(p
);
1131 return log_debug_errno(r
, "Failed to mark %s for auto-removal: %m", p
->name
);
1133 p
->relinquished
= true;
1140 int root_hash_load(const char *image
, void **ret
, size_t *ret_size
) {
1141 _cleanup_free_
char *text
= NULL
;
1142 _cleanup_free_
void *k
= NULL
;
1150 if (is_device_path(image
)) {
1151 /* If we are asked to load the root hash for a device node, exit early */
1157 r
= getxattr_malloc(image
, "user.verity.roothash", &text
, true);
1161 if (!IN_SET(r
, -ENODATA
, -EOPNOTSUPP
, -ENOENT
))
1164 fn
= newa(char, strlen(image
) + strlen(".roothash") + 1);
1165 n
= stpcpy(fn
, image
);
1166 e
= endswith(fn
, ".raw");
1170 strcpy(n
, ".roothash");
1172 r
= read_one_line_file(fn
, &text
);
1182 r
= unhexmem(text
, strlen(text
), &k
, &l
);
1185 if (l
< sizeof(sd_id128_t
))
1196 static const char *const partition_designator_table
[] = {
1197 [PARTITION_ROOT
] = "root",
1198 [PARTITION_ROOT_SECONDARY
] = "root-secondary",
1199 [PARTITION_HOME
] = "home",
1200 [PARTITION_SRV
] = "srv",
1201 [PARTITION_ESP
] = "esp",
1202 [PARTITION_SWAP
] = "swap",
1203 [PARTITION_ROOT_VERITY
] = "root-verity",
1204 [PARTITION_ROOT_SECONDARY_VERITY
] = "root-secondary-verity",
1207 DEFINE_STRING_TABLE_LOOKUP(partition_designator
, int);