grub2/0382-cryptodisk-Add-infrastructure-to-pass-data-from-cryp.patch
Nicolas Frayer 6eaa34fe07 Add several CVE fixes
- Resolves: CVE-2024-45779 CVE-2024-45778 CVE-2025-1118
- Resolves: CVE-2025-0677 CVE-2024-45782 CVE-2025-0690
- Resolves: CVE-2024-45783 CVE-2025-0624 CVE-2024-45776
- Resolves: CVE-2025-0622 CVE-2024-45774 CVE-2024-45775
- Resolves: CVE-2024-45781 CVE-2024-45780
- Resolves: #RHEL-79700
- Resolves: #RHEL-79341
- Resolves: #RHEL-79875
- Resolves: #RHEL-79849
- Resolves: #RHEL-79707
- Resolves: #RHEL-79857
- Resolves: #RHEL-79709
- Resolves: #RHEL-79846
- Resolves: #RHEL-75737
- Resolves: #RHEL-79713
- Resolves: #RHEL-73785
- Resolves: #RHEL-73787
- Resolves: #RHEL-79704
- Resolves: #RHEL-79702

Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
2025-02-18 19:06:15 +01:00

250 lines
8.7 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Glenn Washburn <development@efficientek.com>
Date: Thu, 9 Dec 2021 11:14:55 -0600
Subject: [PATCH] cryptodisk: Add infrastructure to pass data from cryptomount
to cryptodisk modules
Previously, the cryptomount arguments were passed by global variable and
function call argument, neither of which are ideal. This change passes data
via a grub_cryptomount_args struct, which can be added to over time as
opposed to continually adding arguments to the cryptodisk scan and
recover_key.
As an example, passing a password as a cryptomount argument is implemented.
However, the backends are not implemented, so testing this will return a not
implemented error.
Also, add comments to cryptomount argument parsing to make it more obvious
which argument states are being handled.
Signed-off-by: Glenn Washburn <development@efficientek.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/cryptodisk.c | 31 +++++++++++++++++++++----------
grub-core/disk/geli.c | 6 +++++-
grub-core/disk/luks.c | 7 ++++++-
grub-core/disk/luks2.c | 7 ++++++-
include/grub/cryptodisk.h | 9 ++++++++-
5 files changed, 46 insertions(+), 14 deletions(-)
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index 5a9780b..14c661a 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
/* TRANSLATORS: It's still restricted to cryptodisks only. */
{"all", 'a', 0, N_("Mount all."), 0, 0},
{"boot", 'b', 0, N_("Mount all volumes with `boot' flag set."), 0, 0},
+ {"password", 'p', 0, N_("Password to open volumes."), 0, ARG_TYPE_STRING},
{0, 0, 0, 0, 0, 0}
};
@@ -996,7 +997,9 @@ cryptodisk_close (grub_cryptodisk_t dev)
}
static grub_cryptodisk_t
-grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
+grub_cryptodisk_scan_device_real (const char *name,
+ grub_disk_t source,
+ grub_cryptomount_args_t cargs)
{
grub_err_t err;
grub_cryptodisk_t dev;
@@ -1015,7 +1018,7 @@ grub_cryptodisk_scan_device_real (const char *name, grub_disk_t source)
if (!dev)
continue;
- err = cr->recover_key (source, dev);
+ err = cr->recover_key (source, dev, cargs);
if (err)
{
cryptodisk_close (dev);
@@ -1080,11 +1083,12 @@ grub_cryptodisk_cheat_mount (const char *sourcedev, const char *cheat)
static int
grub_cryptodisk_scan_device (const char *name,
- void *data __attribute__ ((unused)))
+ void *data)
{
int ret = 0;
grub_disk_t source;
grub_cryptodisk_t dev;
+ grub_cryptomount_args_t cargs = data;
grub_errno = GRUB_ERR_NONE;
/* Try to open disk. */
@@ -1095,7 +1099,7 @@ grub_cryptodisk_scan_device (const char *name,
return 0;
}
- dev = grub_cryptodisk_scan_device_real (name, source);
+ dev = grub_cryptodisk_scan_device_real (name, source, cargs);
if (dev)
{
ret = (search_uuid != NULL && grub_strcasecmp (search_uuid, dev->uuid) == 0);
@@ -1124,6 +1128,7 @@ static grub_err_t
grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
{
struct grub_arg_list *state = ctxt->state;
+ struct grub_cryptomount_args cargs = {0};
if (argc < 1 && !state[1].set && !state[2].set)
return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
@@ -1131,7 +1136,13 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
if (grub_cryptodisk_list == NULL)
return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
- if (state[0].set)
+ if (state[3].set) /* password */
+ {
+ cargs.key_data = (grub_uint8_t *) state[3].arg;
+ cargs.key_len = grub_strlen (state[3].arg);
+ }
+
+ if (state[0].set) /* uuid */
{
int found_uuid;
grub_cryptodisk_t dev;
@@ -1146,7 +1157,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
check_boot = state[2].set;
search_uuid = args[0];
- found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
+ found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
search_uuid = NULL;
if (found_uuid)
@@ -1163,11 +1174,11 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
}
return grub_errno;
}
- else if (state[1].set || (argc == 0 && state[2].set))
+ else if (state[1].set || (argc == 0 && state[2].set)) /* -a|-b */
{
search_uuid = NULL;
check_boot = state[2].set;
- grub_device_iterate (&grub_cryptodisk_scan_device, NULL);
+ grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
search_uuid = NULL;
return GRUB_ERR_NONE;
}
@@ -1208,7 +1219,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
return GRUB_ERR_NONE;
}
- dev = grub_cryptodisk_scan_device_real (diskname, disk);
+ dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs);
grub_disk_close (disk);
if (disklast)
@@ -1347,7 +1358,7 @@ GRUB_MOD_INIT (cryptodisk)
{
grub_disk_dev_register (&grub_cryptodisk_dev);
cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
- N_("SOURCE|-u UUID|-a|-b"),
+ N_("[-p password] <SOURCE|-u UUID|-a|-b>"),
N_("Mount a crypto device."), options);
grub_procfs_register ("luks_script", &luks_script);
}
diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
index 2f34a35..777da3a 100644
--- a/grub-core/disk/geli.c
+++ b/grub-core/disk/geli.c
@@ -398,7 +398,7 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
}
static grub_err_t
-recover_key (grub_disk_t source, grub_cryptodisk_t dev)
+recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs)
{
grub_size_t keysize;
grub_uint8_t digest[GRUB_CRYPTO_MAX_MDLEN];
@@ -414,6 +414,10 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev)
grub_disk_addr_t sector;
grub_err_t err;
+ /* Keyfiles are not implemented yet */
+ if (cargs->key_data != NULL || cargs->key_len)
+ return GRUB_ERR_NOT_IMPLEMENTED_YET;
+
if (dev->cipher->cipher->blocksize > GRUB_CRYPTO_MAX_CIPHER_BLOCKSIZE)
return grub_error (GRUB_ERR_BUG, "cipher block is too long");
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
index 13103ea..c5858fc 100644
--- a/grub-core/disk/luks.c
+++ b/grub-core/disk/luks.c
@@ -152,7 +152,8 @@ configure_ciphers (grub_disk_t disk, const char *check_uuid,
static grub_err_t
luks_recover_key (grub_disk_t source,
- grub_cryptodisk_t dev)
+ grub_cryptodisk_t dev,
+ grub_cryptomount_args_t cargs)
{
struct grub_luks_phdr header;
grub_size_t keysize;
@@ -165,6 +166,10 @@ luks_recover_key (grub_disk_t source,
grub_size_t max_stripes = 1;
char *tmp;
+ /* Keyfiles are not implemented yet */
+ if (cargs->key_data != NULL || cargs->key_len)
+ return GRUB_ERR_NOT_IMPLEMENTED_YET;
+
err = grub_disk_read (source, 0, 0, sizeof (header), &header);
if (err)
return err;
diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
index c917a5f..8a9f42d 100644
--- a/grub-core/disk/luks2.c
+++ b/grub-core/disk/luks2.c
@@ -542,7 +542,8 @@ luks2_decrypt_key (grub_uint8_t *out_key,
static grub_err_t
luks2_recover_key (grub_disk_t source,
- grub_cryptodisk_t crypt)
+ grub_cryptodisk_t crypt,
+ grub_cryptomount_args_t cargs)
{
grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
char passphrase[MAX_PASSPHRASE], cipher[32];
@@ -556,6 +557,10 @@ luks2_recover_key (grub_disk_t source,
grub_json_t *json = NULL, keyslots;
grub_err_t ret;
+ /* Keyfiles are not implemented yet */
+ if (cargs->key_data != NULL || cargs->key_len)
+ return GRUB_ERR_NOT_IMPLEMENTED_YET;
+
ret = luks2_read_header (source, &header);
if (ret)
return ret;
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
index dcf17fb..282f8ac 100644
--- a/include/grub/cryptodisk.h
+++ b/include/grub/cryptodisk.h
@@ -66,6 +66,13 @@ typedef gcry_err_code_t
(*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev,
grub_uint64_t zoneno);
+struct grub_cryptomount_args
+{
+ grub_uint8_t *key_data;
+ grub_size_t key_len;
+};
+typedef struct grub_cryptomount_args *grub_cryptomount_args_t;
+
struct grub_cryptodisk
{
struct grub_cryptodisk *next;
@@ -119,7 +126,7 @@ struct grub_cryptodisk_dev
grub_cryptodisk_t (*scan) (grub_disk_t disk, const char *check_uuid,
int boot_only);
- grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev);
+ grub_err_t (*recover_key) (grub_disk_t disk, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs);
};
typedef struct grub_cryptodisk_dev *grub_cryptodisk_dev_t;