]> git.proxmox.com Git - grub2.git/blob - debian/patches/osdep-devmapper-getroot-set-up-cheated-luks2-cryptodisk-mount-from-dm-parameters.patch
Try again, argh printf types
[grub2.git] / debian / patches / osdep-devmapper-getroot-set-up-cheated-luks2-cryptodisk-mount-from-dm-parameters.patch
1 From: Josselin Poiret <dev@jpoiret.xyz>
2 Date: Thu, 12 Jan 2023 17:05:09 -0600
3 Subject: osdep/devmapper/getroot: Set up cheated LUKS2 cryptodisk mount from
4 DM parameters
5 Origin: https://git.savannah.gnu.org/cgit/grub.git/commit/?id=aa5172a55cfabdd0bed3161ad44fc228b9d019f7
6 Bug-Debian: https://bugs.debian.org/1028301
7
8 This lets a LUKS2 cryptodisk have its cipher and hash filled out,
9 otherwise they wouldn't be initialized if cheat mounted.
10
11 Signed-off-by: Josselin Poiret <dev@jpoiret.xyz>
12 Tested-by: Glenn Washburn <development@efficientek.com>
13 Reviewed-by: Patrick Steinhardt <ps@pks.im>
14 Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
15 ---
16 grub-core/osdep/devmapper/getroot.c | 107 +++++++++++++++++++++++++++++++++++-
17 1 file changed, 106 insertions(+), 1 deletion(-)
18
19 diff --git a/grub-core/osdep/devmapper/getroot.c b/grub-core/osdep/devmapper/getroot.c
20 index 2bf4264..cc3f7da 100644
21 --- a/grub-core/osdep/devmapper/getroot.c
22 +++ b/grub-core/osdep/devmapper/getroot.c
23 @@ -51,6 +51,8 @@
24 #include <grub/emu/misc.h>
25 #include <grub/emu/hostdisk.h>
26
27 +#include <grub/cryptodisk.h>
28 +
29 static int
30 grub_util_open_dm (const char *os_dev, struct dm_tree **tree,
31 struct dm_tree_node **node)
32 @@ -186,7 +188,6 @@ grub_util_pull_devmapper (const char *os_dev)
33 && lastsubdev)
34 {
35 char *grdev = grub_util_get_grub_dev (lastsubdev);
36 - dm_tree_free (tree);
37 if (grdev)
38 {
39 grub_err_t err;
40 @@ -194,7 +195,111 @@ grub_util_pull_devmapper (const char *os_dev)
41 if (err)
42 grub_util_error (_("can't mount encrypted volume `%s': %s"),
43 lastsubdev, grub_errmsg);
44 + if (strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0)
45 + {
46 + /*
47 + * Set LUKS2 cipher from dm parameters, since it is not
48 + * possible to determine the correct one without
49 + * unlocking, as there might be multiple segments.
50 + */
51 + grub_disk_t source;
52 + grub_cryptodisk_t cryptodisk;
53 + grub_uint64_t start, length;
54 + char *target_type;
55 + char *params;
56 + const char *name;
57 + char *cipher, *cipher_mode;
58 + struct dm_task *dmt;
59 + char *seek_head, *c;
60 + unsigned int remaining;
61 +
62 + source = grub_disk_open (grdev);
63 + if (! source)
64 + grub_util_error (_("cannot open grub disk `%s'"), grdev);
65 + cryptodisk = grub_cryptodisk_get_by_source_disk (source);
66 + if (! cryptodisk)
67 + grub_util_error (_("cannot get cryptodisk from source disk `%s'"), grdev);
68 + grub_disk_close (source);
69 +
70 + /*
71 + * The following function always returns a non-NULL pointer,
72 + * but the string may be empty if the relevant info is not present.
73 + */
74 + name = dm_tree_node_get_name (node);
75 + if (*name == '\0')
76 + grub_util_error (_("cannot get dm node name for grub dev `%s'"), grdev);
77 +
78 + grub_util_info ("populating parameters of cryptomount `%s' from DM device `%s'",
79 + uuid, name);
80 +
81 + dmt = dm_task_create (DM_DEVICE_TABLE);
82 + if (dmt == NULL)
83 + grub_util_error (_("can't create dm task DM_DEVICE_TABLE"));
84 + if (dm_task_set_name (dmt, name) == 0)
85 + grub_util_error (_("can't set dm task name to `%s'"), name);
86 + if (dm_task_run (dmt) == 0)
87 + grub_util_error (_("can't run dm task for `%s'"), name);
88 + /*
89 + * dm_get_next_target() doesn't have any error modes, everything has
90 + * been handled by dm_task_run().
91 + */
92 + dm_get_next_target (dmt, NULL, &start, &length,
93 + &target_type, &params);
94 + if (strncmp (target_type, "crypt", sizeof ("crypt")) != 0)
95 + grub_util_error (_("dm target of type `%s' is not `crypt'"), target_type);
96 +
97 + /*
98 + * The dm target parameters for dm-crypt are
99 + * <cipher> <key> <iv_offset> <device path> <offset> [<#opt_params> <opt_param1> ...]
100 + */
101 + c = params;
102 + remaining = grub_strlen (c);
103 +
104 + /* First, get the cipher name from the cipher. */
105 + seek_head = grub_memchr (c, '-', remaining);
106 + if (seek_head == NULL)
107 + grub_util_error (_("can't get cipher from dm-crypt parameters `%s'"),
108 + params);
109 + cipher = grub_strndup (c, seek_head - c);
110 + if (cipher == NULL)
111 + grub_util_error (_("could not strndup cipher of length `%lu'"), (unsigned long)(seek_head - c));
112 + remaining -= seek_head - c + 1;
113 + c = seek_head + 1;
114 +
115 + /* Now, the cipher mode. */
116 + seek_head = grub_memchr (c, ' ', remaining);
117 + if (seek_head == NULL)
118 + grub_util_error (_("can't get cipher mode from dm-crypt parameters `%s'"),
119 + params);
120 + cipher_mode = grub_strndup (c, seek_head - c);
121 + if (cipher_mode == NULL)
122 + grub_util_error (_("could not strndup cipher_mode of length `%lu'"), (unsigned long)(seek_head - c));
123 +
124 + remaining -= seek_head - c + 1;
125 + c = seek_head + 1;
126 +
127 + err = grub_cryptodisk_setcipher (cryptodisk, cipher, cipher_mode);
128 + if (err)
129 + grub_util_error (_("can't set cipher of cryptodisk `%s' to `%s' with mode `%s'"),
130 + uuid, cipher, cipher_mode);
131 +
132 + grub_free (cipher);
133 + grub_free (cipher_mode);
134 +
135 + /*
136 + * This is the only hash usable by PBKDF2, and we don't
137 + * have Argon2 support yet, so set it by default,
138 + * otherwise grub-probe would miss the required
139 + * abstraction.
140 + */
141 + cryptodisk->hash = grub_crypto_lookup_md_by_name ("sha256");
142 + if (cryptodisk->hash == NULL)
143 + grub_util_error (_("can't lookup hash sha256 by name"));
144 +
145 + dm_task_destroy (dmt);
146 + }
147 }
148 + dm_tree_free (tree);
149 grub_free (grdev);
150 }
151 else
152 --
153 cgit v1.1
154