[PATCH] cryptodisk: Fix Coverity use after free bug
The Coverity output is: *** CID 366905: Memory - illegal accesses (USE_AFTER_FREE) /grub-core/disk/cryptodisk.c: 1064 in grub_cryptodisk_scan_device_real() 1058 cleanup: 1059 if (askpass) 1060 { 1061 cargs->key_len = 0; 1062 grub_free (cargs->key_data); 1063 } >>> CID 366905: Memory - illegal accesses (USE_AFTER_FREE) >>> Using freed pointer "dev". 1064 return dev; 1065 } 1066 1067 #ifdef GRUB_UTIL 1068 #include 1069 grub_err_t Here the 'dev' variable can point to a freed cryptodisk device if the function grub_cryptodisk_insert() fails. This can happen only on a OOM condition, but when this happens grub_cryptodisk_insert() calls grub_free on the passed device. Since grub_cryptodisk_scan_device_real() assumes that grub_cryptodisk_insert() is always successful, it will return the device, though the device was freed. Change grub_cryptodisk_insert() to not free the passed device on failure. Then on grub_cryptodisk_insert() failure, free the device pointer. This is done by going to the label 'error', which will call cryptodisk_close() to free the device and set the device pointer to NULL, so that a pointer to freed memory is not returned. Signed-off-by: Glenn Washburn --- Having reviewed the Coverity error, I believe this is the fix needed to resolve the use after free reported by Coverity. However, I do not currently have Coverity setup, so I don't have a way to test if this is both necessary and sufficient to resolve the Coverity error. Regardess, I do believe that is does fix a real use after free bug. Glenn --- grub-core/disk/cryptodisk.c | 9 - 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 497097394..e7c4795fd 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -889,10 +889,7 @@ grub_cryptodisk_insert (grub_cryptodisk_t newdev, const char *name, { newdev->source = grub_strdup (name); if (!newdev->source) -{ - grub_free (newdev); - return grub_errno; -} +return grub_errno; newdev->id = last_cryptodisk_id++; newdev->source_id = source->id; @@ -1044,7 +1041,9 @@ grub_cryptodisk_scan_device_real (const char *name, if (ret != GRUB_ERR_NONE) goto error; -grub_cryptodisk_insert (dev, name, source); +ret = grub_cryptodisk_insert (dev, name, source); +if (ret != GRUB_ERR_NONE) + goto error; goto cleanup; } -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v8 0/7] Cryptodisk detached headers and key files
This patch series is an updated version of the v7 sent by Denis Carikli with modifications to reflect changes in argument passing to crypto backends. The previous patch #6 titled "Add support for LUKS1 key files" has been removed as its not needed anymore. Patches #6 and #7 are new, for updating the cryptomount help string and adding support for detached headers in the LUKS2 crypto backend, respectively. I modified the commit tags from v7 as seemed appropriate to me, but they may not be desirable as-is. Glenn Denis 'GNUtoo' Carikli (2): cryptodisk: luks: unify grub_cryptodisk_dev function names cryptodisk: geli: unify grub_cryptodisk_dev function names Glenn Washburn (3): cryptodisk: enable the backends to implement detached headers cryptodisk: Improve cryptomount short help string luks2: Add detached header support John Lane (2): cryptodisk: add support for LUKS1 detached headers cryptodisk: enable the backends to implement key files grub-core/disk/cryptodisk.c | 100 +++- grub-core/disk/geli.c | 18 +-- grub-core/disk/luks.c | 48 + grub-core/disk/luks2.c | 59 + include/grub/cryptodisk.h | 4 ++ include/grub/file.h | 4 ++ 6 files changed, 208 insertions(+), 25 deletions(-) Range-diff against v7: 1: 2ad229622 ! 1: e301e06b2 cryptodisk: luks: unify grub_cryptodisk_dev function names @@ grub-core/disk/luks.c: gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, gr grub_size_t blocknumbers); static grub_cryptodisk_t --configure_ciphers (grub_disk_t disk, const char *check_uuid, -- int check_boot) -+luks_scan (grub_disk_t disk, const char *check_uuid, int check_boot) +-configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) ++luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) { grub_cryptodisk_t newdev; const char *iptr; 2: f5fd41a71 ! 2: e759d96cd cryptodisk: geli: unify grub_cryptodisk_dev function names @@ grub-core/disk/geli.c: grub_util_get_geli_uuid (const char *dev) #endif static grub_cryptodisk_t --configure_ciphers (grub_disk_t disk, const char *check_uuid, -- int boot_only) -+geli_scan (grub_disk_t disk, const char *check_uuid, int boot_only) +-configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) ++geli_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) { grub_cryptodisk_t newdev; struct grub_geli_phdr header; -@@ grub-core/disk/geli.c: configure_ciphers (grub_disk_t disk, const char *check_uuid, +@@ grub-core/disk/geli.c: configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) } static grub_err_t --recover_key (grub_disk_t source, grub_cryptodisk_t dev) -+geli_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) ++geli_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]; -@@ grub-core/disk/geli.c: recover_key (grub_disk_t source, grub_cryptodisk_t dev) +@@ grub-core/disk/geli.c: recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t } struct grub_cryptodisk_dev geli_crypto = { 3: 365839627 < -: - cryptodisk: enable the backends to implement detached headers -: - > 3: ee04480ba cryptodisk: enable the backends to implement detached headers 4: 1e1257bb6 ! 4: 69684640b cryptodisk: add support for LUKS1 detached headers @@ Commit message Signed-off-by: John Lane gnu...@cyberdimension.org: rebase, small fixes, commit message Signed-off-by: Denis 'GNUtoo' Carikli -Reviewed-by: Patrick Steinhardt +developm...@efficientek.com: rebase ## grub-core/disk/luks.c ## @@ @@ grub-core/disk/luks.c #include #include #include -@@ grub-core/disk/luks.c: luks_scan (grub_disk_t disk, const char *check_uuid, int check_boot, +@@ grub-core/disk/luks.c: luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) char ciphername[sizeof (header.cipherName) + 1]; char ciphermode[sizeof (header.cipherMode) + 1]; char hashspec[sizeof (header.hashSpec) + 1]; - grub_err_t err; - - /* Detached headers are not implemented yet */ -- if (hdr) +- if (cargs->hdr_file) -return NULL; + grub_err_t err = GRUB_ERR_NONE; - if (check_boot) + if (cargs->check_boot) return NULL; /* Read the LUKS header. */ - err = grub_disk_read (disk, 0, 0, sizeof (header), &header); -+ if (hdr) ++ if (cargs->hdr_file) +{ -+ if
[PATCH v8 1/7] cryptodisk: luks: unify grub_cryptodisk_dev function names
From: Denis 'GNUtoo' Carikli Signed-off-by: Denis 'GNUtoo' Carikli Reviewed-by: Patrick Steinhardt Signed-off-by: Glenn Washburn --- grub-core/disk/luks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index f0feb3844..d57257b3e 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -63,7 +63,7 @@ gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, grub_size_t blocknumbers); static grub_cryptodisk_t -configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) +luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) { grub_cryptodisk_t newdev; const char *iptr; @@ -297,7 +297,7 @@ luks_recover_key (grub_disk_t source, } struct grub_cryptodisk_dev luks_crypto = { - .scan = configure_ciphers, + .scan = luks_scan, .recover_key = luks_recover_key }; -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v8 3/7] cryptodisk: enable the backends to implement detached headers
Signed-off-by: John Lane gnu...@cyberdimension.org: rebase, patch split, small fixes, commit message Signed-off-by: Denis 'GNUtoo' Carikli developm...@efficientek.com: rebase, rework for cryptomount parameter passing Signed-off-by: Glenn Washburn --- grub-core/disk/cryptodisk.c | 15 ++- grub-core/disk/geli.c | 10 ++ grub-core/disk/luks.c | 8 grub-core/disk/luks2.c | 8 include/grub/cryptodisk.h | 2 ++ include/grub/file.h | 2 ++ 6 files changed, 44 insertions(+), 1 deletion(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index 497097394..e90f680f0 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -42,6 +42,7 @@ static const struct grub_arg_option options[] = {"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}, +{"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING}, {0, 0, 0, 0, 0, 0} }; @@ -1173,6 +1174,18 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) cargs.key_len = grub_strlen (state[3].arg); } + if (state[4].set) /* Detached header */ +{ + if (state[0].set) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("Cannot use UUID lookup with detached header")); + + cargs.hdr_file = grub_file_open (state[4].arg, + GRUB_FILE_TYPE_CRYPTODISK_DETACHED_HEADER); + if (!cargs.hdr_file) + return grub_errno; +} + if (state[0].set) /* uuid */ { int found_uuid; @@ -1385,7 +1398,7 @@ GRUB_MOD_INIT (cryptodisk) { grub_disk_dev_register (&grub_cryptodisk_dev); cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, - N_("[-p password] "), + N_("[-p password] [-H file] "), 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 5b3a11881..0b8046746 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -121,6 +122,7 @@ enum /* FIXME: support version 0. */ /* FIXME: support big-endian pre-version-4 volumes. */ +/* FIXME: support for detached headers. */ /* FIXME: support for keyfiles. */ /* FIXME: support for HMAC. */ const char *algorithms[] = { @@ -252,6 +254,10 @@ geli_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) grub_disk_addr_t sector; grub_err_t err; + /* Detached headers are not implemented yet */ + if (cargs->hdr_file) +return NULL; + if (2 * GRUB_MD_SHA256->mdlen + 1 > GRUB_CRYPTODISK_MAX_UUID_LENGTH) return NULL; @@ -412,6 +418,10 @@ geli_recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_ar if (cargs->key_data == NULL || cargs->key_len == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); + /* Detached headers are not implemented yet */ + if (cargs->hdr_file) + 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 d57257b3e..032a9db3c 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -75,6 +75,10 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) char hashspec[sizeof (header.hashSpec) + 1]; grub_err_t err; + /* Detached headers are not implemented yet */ + if (cargs->hdr_file) +return NULL; + if (cargs->check_boot) return NULL; @@ -164,6 +168,10 @@ luks_recover_key (grub_disk_t source, if (cargs->key_data == NULL || cargs->key_len == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); + /* Detached headers are not implemented yet */ + if (cargs->hdr_file) + 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 ccfacb63a..567368f11 100644 --- a/grub-core/disk/luks2.c +++ b/grub-core/disk/luks2.c @@ -353,6 +353,10 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) char uuid[sizeof (header.uuid) + 1]; grub_size_t i, j; + /* Detached headers are not implemented yet */ + if (cargs->hdr_file) +return NULL; + if (cargs->check_boot) return NULL; @@ -560,6 +564,10 @@ luks2_recover_key (grub_disk_t source, if (cargs->key_data == NULL || cargs->key_len == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); + /* Detached headers are not implemented yet */ + if (cargs->hdr_file) + return GRUB_ERR_NOT_IMPLE
[PATCH v8 6/7] cryptodisk: Improve cryptomount short help string
Signed-off-by: Glenn Washburn --- grub-core/disk/cryptodisk.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index ea8ed20e2..319c84a6c 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -1481,7 +1481,9 @@ GRUB_MOD_INIT (cryptodisk) { grub_disk_dev_register (&grub_cryptodisk_dev); cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, - N_("[-p password] [-H file] "), + N_("[-p password] [-k keyfile] [-O keyoffset]" +" [-S keysize] [-H file]" +" "), N_("Mount a crypto device."), options); grub_procfs_register ("luks_script", &luks_script); } -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v8 2/7] cryptodisk: geli: unify grub_cryptodisk_dev function names
From: Denis 'GNUtoo' Carikli Signed-off-by: Denis 'GNUtoo' Carikli Reviewed-by: Patrick Steinhardt Signed-off-by: Glenn Washburn --- grub-core/disk/geli.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c index 23789c43f..5b3a11881 100644 --- a/grub-core/disk/geli.c +++ b/grub-core/disk/geli.c @@ -240,7 +240,7 @@ grub_util_get_geli_uuid (const char *dev) #endif static grub_cryptodisk_t -configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) +geli_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) { grub_cryptodisk_t newdev; struct grub_geli_phdr header; @@ -395,7 +395,7 @@ configure_ciphers (grub_disk_t disk, grub_cryptomount_args_t cargs) } static grub_err_t -recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t cargs) +geli_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]; @@ -567,8 +567,8 @@ recover_key (grub_disk_t source, grub_cryptodisk_t dev, grub_cryptomount_args_t } struct grub_cryptodisk_dev geli_crypto = { - .scan = configure_ciphers, - .recover_key = recover_key + .scan = geli_scan, + .recover_key = geli_recover_key }; GRUB_MOD_INIT (geli) -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v8 5/7] cryptodisk: enable the backends to implement key files
From: John Lane Signed-off-by: John Lane gnu...@cyberdimension.org: rebase, patch split, small fixes, commit message Signed-off-by: Denis 'GNUtoo' Carikli developm...@efficientek.com: rebase and rework to use cryptomount arg passing Signed-off-by: Glenn Washburn --- grub-core/disk/cryptodisk.c | 83 + include/grub/cryptodisk.h | 2 + include/grub/file.h | 2 + 3 files changed, 87 insertions(+) diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c index e90f680f0..ea8ed20e2 100644 --- a/grub-core/disk/cryptodisk.c +++ b/grub-core/disk/cryptodisk.c @@ -43,6 +43,9 @@ static const struct grub_arg_option options[] = {"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}, {"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING}, +{"keyfile", 'k', 0, N_("Key file"), 0, ARG_TYPE_STRING}, +{"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT}, +{"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT}, {0, 0, 0, 0, 0, 0} }; @@ -1186,6 +1189,86 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) return grub_errno; } + if (state[5].set) /* keyfile */ +{ + const char *p = NULL; + grub_file_t keyfile; + int keyfile_offset; + grub_size_t requested_keyfile_size = 0; + + + if (state[6].set) /* keyfile-offset */ + { + keyfile_offset = grub_strtoul (state[6].arg, &p, 0); + + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + if (*p != '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unrecognized number")); + } + else + { + keyfile_offset = 0; + } + + if (state[7].set) /* keyfile-size */ + { + requested_keyfile_size = grub_strtoul (state[7].arg, &p, 0); + + if (*p != '\0') + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("unrecognized number")); + + if (grub_errno != GRUB_ERR_NONE) + return grub_errno; + + if (requested_keyfile_size > GRUB_CRYPTODISK_MAX_KEYFILE_SIZE) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("Key file size exceeds maximum (%d)\n"), + GRUB_CRYPTODISK_MAX_KEYFILE_SIZE); + + if (requested_keyfile_size == 0) + return grub_error (GRUB_ERR_OUT_OF_RANGE, + N_("Key file size is 0\n")); + } + + keyfile = grub_file_open (state[5].arg, + GRUB_FILE_TYPE_CRYPTODISK_ENCRYPTION_KEY); + if (!keyfile) + return grub_errno; + + if (grub_file_seek (keyfile, keyfile_offset) == (grub_off_t)-1) + return grub_errno; + + if (requested_keyfile_size) + { + if (requested_keyfile_size > (keyfile->size - keyfile_offset)) + return grub_error (GRUB_ERR_FILE_READ_ERROR, + N_("Keyfile is too small: " + "requested %" PRIuGRUB_SIZE " bytes, " + "but the file only has %" PRIuGRUB_UINT64_T + " bytes.\n"), + requested_keyfile_size, + keyfile->size); + + cargs.key_len = requested_keyfile_size; + } + else + { + cargs.key_len = keyfile->size - keyfile_offset; + } + + cargs.key_data = grub_malloc (cargs.key_len); + if (!cargs.key_data) + return GRUB_ERR_OUT_OF_MEMORY; + + if (grub_file_read (keyfile, cargs.key_data, cargs.key_len) != (grub_ssize_t) cargs.key_len) + return grub_error (GRUB_ERR_FILE_READ_ERROR, + (N_("Error reading key file\n"))); +} + if (state[0].set) /* uuid */ { int found_uuid; diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h index 9fe451de9..d94df68b6 100644 --- a/include/grub/cryptodisk.h +++ b/include/grub/cryptodisk.h @@ -62,6 +62,8 @@ typedef enum #define GRUB_CRYPTODISK_MAX_KEYLEN 128 #define GRUB_CRYPTODISK_MAX_PASSPHRASE 256 +#define GRUB_CRYPTODISK_MAX_KEYFILE_SIZE 8192 + struct grub_cryptodisk; typedef gcry_err_code_t diff --git a/include/grub/file.h b/include/grub/file.h index 3a3c49a04..2d5d16cd2 100644 --- a/include/grub/file.h +++ b/include/grub/file.h @@ -92,6 +92,8 @@ enum grub_file_type GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY, /* File holding the encryption metadata header */ GRUB_FILE_TYPE_CRYPTODISK_DETACHED_HEADER, +/* File holding the encryption key */ +GRUB_FILE_TYPE_CRYPTODISK_ENCRYPTION_KEY, /* File we open n grub-fstest. */ GRUB_FILE_TYPE_FSTEST, /* File we open n grub-mount. */ -- 2.27.0 ___
[PATCH v8 7/7] luks2: Add detached header support
Signed-off-by: Glenn Washburn --- grub-core/disk/luks2.c | 67 ++ 1 file changed, 49 insertions(+), 18 deletions(-) diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c index 567368f11..e92c28d45 100644 --- a/grub-core/disk/luks2.c +++ b/grub-core/disk/luks2.c @@ -313,13 +313,22 @@ luks2_get_keyslot (grub_luks2_keyslot_t *k, grub_luks2_digest_t *d, grub_luks2_s /* Determine whether to use primary or secondary header */ static grub_err_t -luks2_read_header (grub_disk_t disk, grub_luks2_header_t *outhdr) +luks2_read_header (grub_disk_t disk, grub_file_t hdr_file, grub_luks2_header_t *outhdr) { grub_luks2_header_t primary, secondary, *header = &primary; - grub_err_t ret; + grub_err_t ret = GRUB_ERR_NONE; /* Read the primary LUKS header. */ - ret = grub_disk_read (disk, 0, 0, sizeof (primary), &primary); + if (hdr_file) +{ + if (grub_file_seek (hdr_file, 0) == (grub_off_t) -1) + ret = grub_errno; + + else if (grub_file_read (hdr_file, &primary, sizeof (primary)) != sizeof (primary)) + ret = grub_errno; +} + else +ret = grub_disk_read (disk, 0, 0, sizeof (primary), &primary); if (ret) return ret; @@ -329,7 +338,16 @@ luks2_read_header (grub_disk_t disk, grub_luks2_header_t *outhdr) return GRUB_ERR_BAD_SIGNATURE; /* Read the secondary header. */ - ret = grub_disk_read (disk, 0, grub_be_to_cpu64 (primary.hdr_size), sizeof (secondary), &secondary); + if (hdr_file) +{ + if (grub_file_seek (hdr_file, grub_be_to_cpu64 (primary.hdr_size)) == (grub_off_t) -1) + ret = grub_errno; + + else if (grub_file_read (hdr_file, &secondary, sizeof (secondary)) != sizeof (secondary)) + ret = grub_errno; +} + else +ret = grub_disk_read (disk, 0, grub_be_to_cpu64 (primary.hdr_size), sizeof (secondary), &secondary); if (ret) return ret; @@ -353,14 +371,10 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) char uuid[sizeof (header.uuid) + 1]; grub_size_t i, j; - /* Detached headers are not implemented yet */ - if (cargs->hdr_file) -return NULL; - if (cargs->check_boot) return NULL; - if (luks2_read_header (disk, &header)) + if (luks2_read_header (disk, cargs->hdr_file, &header)) { grub_errno = GRUB_ERR_NONE; return NULL; @@ -427,6 +441,7 @@ luks2_verify_key (grub_luks2_digest_t *d, grub_uint8_t *candidate_key, static grub_err_t luks2_decrypt_key (grub_uint8_t *out_key, grub_disk_t source, grub_cryptodisk_t crypt, + grub_cryptomount_args_t cargs, grub_luks2_keyslot_t *k, const grub_uint8_t *passphrase, grub_size_t passphraselen) { @@ -502,7 +517,17 @@ luks2_decrypt_key (grub_uint8_t *out_key, } grub_errno = GRUB_ERR_NONE; - ret = grub_disk_read (source, 0, k->area.offset, k->area.size, split_key); + if (cargs->hdr_file) +{ + if (grub_file_seek (cargs->hdr_file, k->area.offset) == (grub_off_t) -1) + ret = grub_errno; + + else if (grub_file_read (cargs->hdr_file, split_key, k->area.size) != k->area.size) + ret = grub_errno; +} + else +ret = grub_disk_read (source, 0, k->area.offset, k->area.size, split_key); + if (ret) { grub_error (GRUB_ERR_IO, "Read error: %s\n", grub_errmsg); @@ -564,11 +589,7 @@ luks2_recover_key (grub_disk_t source, if (cargs->key_data == NULL || cargs->key_len == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); - /* Detached headers are not implemented yet */ - if (cargs->hdr_file) - return GRUB_ERR_NOT_IMPLEMENTED_YET; - - ret = luks2_read_header (source, &header); + ret = luks2_read_header (source, cargs->hdr_file, &header); if (ret) return ret; @@ -577,8 +598,18 @@ luks2_recover_key (grub_disk_t source, return GRUB_ERR_OUT_OF_MEMORY; /* Read the JSON area. */ - ret = grub_disk_read (source, 0, grub_be_to_cpu64 (header.hdr_offset) + sizeof (header), - grub_be_to_cpu64 (header.hdr_size) - sizeof (header), json_header); + if (cargs->hdr_file) +{ + if (grub_file_seek (cargs->hdr_file, grub_be_to_cpu64 (header.hdr_offset) + sizeof (header)) == (grub_off_t) -1) + ret = grub_errno; + + else if (grub_file_read (cargs->hdr_file, json_header, grub_be_to_cpu64 (header.hdr_size) - sizeof (header)) != (grub_be_to_cpu64 (header.hdr_size) - sizeof (header))) + ret = grub_errno; +} + else +ret = grub_disk_read (source, 0, grub_be_to_cpu64 (header.hdr_offset) + sizeof (header), + grub_be_to_cpu64 (header.hdr_size) - sizeof (header), json_header); + if (ret) goto err; @@ -716,7 +747,7 @@ luks2_recover_key (grub_disk_t source, crypt->total_sectors = max_crypt_sectors - crypt->offset_sectors; } - ret = luks2_decrypt_key (candidate_key, source, crypt, &keyslot, + ret = luks2_decrypt
[PATCH v8 4/7] cryptodisk: add support for LUKS1 detached headers
From: John Lane cryptsetup supports having a detached header through the --header command line argument for both LUKS1 and LUKS2. This adds support for LUKS1 detached headers. Signed-off-by: John Lane gnu...@cyberdimension.org: rebase, small fixes, commit message Signed-off-by: Denis 'GNUtoo' Carikli developm...@efficientek.com: rebase Signed-off-by: Glenn Washburn --- grub-core/disk/luks.c | 48 ++- 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c index 032a9db3c..5a9157608 100644 --- a/grub-core/disk/luks.c +++ b/grub-core/disk/luks.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -73,17 +74,23 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs) char ciphername[sizeof (header.cipherName) + 1]; char ciphermode[sizeof (header.cipherMode) + 1]; char hashspec[sizeof (header.hashSpec) + 1]; - grub_err_t err; - - /* Detached headers are not implemented yet */ - if (cargs->hdr_file) -return NULL; + grub_err_t err = GRUB_ERR_NONE; if (cargs->check_boot) return NULL; /* Read the LUKS header. */ - err = grub_disk_read (disk, 0, 0, sizeof (header), &header); + if (cargs->hdr_file) +{ + if (grub_file_seek (cargs->hdr_file, 0) == (grub_off_t) -1) + return NULL; + + if (grub_file_read (cargs->hdr_file, &header, sizeof (header)) != sizeof (header)) + return NULL; +} + else +err = grub_disk_read (disk, 0, 0, sizeof (header), &header); + if (err) { if (err == GRUB_ERR_OUT_OF_RANGE) @@ -162,17 +169,24 @@ luks_recover_key (grub_disk_t source, grub_uint8_t candidate_digest[sizeof (header.mkDigest)]; unsigned i; grub_size_t length; - grub_err_t err; + grub_err_t err = GRUB_ERR_NONE; grub_size_t max_stripes = 1; + grub_uint32_t sector; if (cargs->key_data == NULL || cargs->key_len == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, "no key data"); - /* Detached headers are not implemented yet */ if (cargs->hdr_file) - return GRUB_ERR_NOT_IMPLEMENTED_YET; +{ + if (grub_file_seek (cargs->hdr_file, 0) == (grub_off_t) -1) + return grub_errno; + + if (grub_file_read (cargs->hdr_file, &header, sizeof (header)) != sizeof (header)) + return grub_errno; +} + else +err = grub_disk_read (source, 0, 0, sizeof (header), &header); - err = grub_disk_read (source, 0, 0, sizeof (header), &header); if (err) return err; @@ -227,13 +241,19 @@ luks_recover_key (grub_disk_t source, return grub_crypto_gcry_error (gcry_err); } + sector = grub_be_to_cpu32 (header.keyblock[i].keyMaterialOffset); length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes)); /* Read and decrypt the key material from the disk. */ - err = grub_disk_read (source, - grub_be_to_cpu32 (header.keyblock - [i].keyMaterialOffset), 0, - length, split_key); + if (cargs->hdr_file) + { +if (grub_file_seek (cargs->hdr_file, sector * 512) == (grub_off_t) -1) + return grub_errno; +if (grub_file_read (cargs->hdr_file, split_key, length) != (grub_ssize_t)length) + return grub_errno; + } + else +err = grub_disk_read (source, sector, 0, length, split_key); if (err) { grub_free (split_key); -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 01/12] grub-shell: Allow specifying non-default trim line contents
This will be useful for tests that have unwanted output from setup. This is not documented because its only intended to be internal at the moment. Also, --no-trim is allowed to explicitly turn off trim. Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 14 +- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 93e9f5148..b409962f1 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -32,6 +32,7 @@ PATH="${builddir}:$PATH" export PATH trim=0 +trim_head=664cbea8-132f-4770-8aa4-1696d59ac35c # Usage: usage # Print the usage. @@ -212,8 +213,13 @@ for option in "$@"; do echo "$0 (GNU GRUB ${PACKAGE_VERSION})" exit 0 ;; --trim) - trim=1 + trim=1 ;; +--trim=*) + trim=2 + trim_head=`echo "$option" | sed -e 's/--trim=//' -e 's/,/ /g'` ;; +--no-trim) + trim=0 ;; --debug) debug=1 ;; --modules=*) @@ -336,8 +342,6 @@ terminal_input ${term} terminal_output ${term} EOF -trim_head=664cbea8-132f-4770-8aa4-1696d59ac35c - if [ $trim = 1 ]; then echo "echo $trim_head" >>${cfgfile} fi @@ -452,8 +456,8 @@ fi do_trim () { -if [ $trim = 1 ]; then - awk '{ if (have_head == 1) print $0; } /664cbea8-132f-4770-8aa4-1696d59ac35c/ { have_head=1; }' +if [ $trim = 1 ] || [ $trim = 2 ]; then + awk '{ if (have_head == 1) print $0; } /'"$trim_head"'/ { have_head=1; }' else cat fi -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 00/12] Grub-shell improvements
Updates since v1: * Improve QEMU logging patch to make sure all data is written to the pipe before exiting (otherwise tests can fail because they don't get the last bit of QEMU output). * Improve QEMU firmware handling to prefer using the -bios option (for older setups) and prefer firmware files found in the source directory so that system firmware can be overridden and systems without packages providing the firmware can be used. The only patch that might be considered a fix, as opposed to an improvement, would be patch #11, which fixes the issue where qemu-mips is given a non-existant machine type. And while this was discussed here on the list as a possible solution, I couldn't get the mips tests working, so I'm not sure it's the right fix. Glenn Glenn Washburn (12): grub-shell: Allow specifying non-default trim line contents grub-shell: Trim line should always be matched from the beginning of the line grub-shell: Only show grub-mkrescue output if it returns an error grub-shell: Allow setting default timeout via GRUB_SHELL_DEFAULT_TIMEOUT envvar grub-shell: Put all generated files into working dir and use better file names grub-shell: Add grub output logfile with grub-shell --debug grub-shell: Set exit status to qemu exit status tests: Allow turning on shell tracing from environment variables grub-shell: Add --verbose to mkrescue when $debug is greater than 2 grub-shell: Only turn on qemu head when large debug value is specified grub-shell: Use malta qemu-mips machine type instead off non-existant indy grub-shell: Add flexibility in QEMU firmware handling tests/util/grub-fs-tester.in | 2 + tests/util/grub-shell.in | 185 +-- 2 files changed, 158 insertions(+), 29 deletions(-) Range-diff against v1: 1: ee0b447e0 = 1: 52df3299f grub-shell: Allow specifying non-default trim line contents 2: 34ce6 = 2: 7c8264aeb grub-shell: Trim line should always be matched from the beginning of the line 3: e2826567c = 3: c17da94e7 grub-shell: Only show grub-mkrescue output if it returns an error 4: 68fa49770 = 4: 27717b949 grub-shell: Allow setting default timeout via GRUB_SHELL_DEFAULT_TIMEOUT envvar 5: e113eba70 = 5: 17dd72798 grub-shell: Put all generated files into working dir and use better file names 6: 8acbe1a63 = 6: 428698acd grub-shell: Add grub output logfile with grub-shell --debug 7: 925d155ea ! 7: cdd28473c grub-shell: Set exit status to qemu exit status @@ tests/util/grub-shell.in: copy_extra_files() { done } ++setup_qemu_logger() { ++cat < "$work_directory/qemu-pipe" | tr -d "\r" | tee "${goutfile}" | do_trim & ++} ++ +ret=0 +mkfifo "$work_directory/qemu-pipe" -+cat < "$work_directory/qemu-pipe" | tr -d "\r" | tee "${goutfile}" | do_trim & if [ x$boot = xnet ]; then netdir="$work_directory/netdir" mkdir -p "$netdir" @@ tests/util/grub-shell.in: if [ x$boot = xnet ]; then cp "${source}" "$netdir/boot/grub/testcase.cfg" [ -z "$files" ] || copy_extra_files "$netdir" $files -timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | tee "${goutfile}" | do_trim ++setup_qemu_logger +timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic > "$work_directory/qemu-pipe" || ret=$? elif [ x$boot = xemu ]; then rootdir="$work_directory/rootdir" @@ tests/util/grub-shell.in: elif [ x$boot = xemu ]; then roottar="$work_directory/root.tar" (cd "$rootdir"; tar cf "$roottar" .) -@builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot/grub" | tr -d "\r" | tee "${goutfile}" | do_trim ++setup_qemu_logger +@builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot/grub" > "$work_directory/qemu-pipe" || ret=$? test -n "$debug" || rm -rf "$rootdir" test -n "$debug" || rm -f "$roottar" else -timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} | cat | tr -d "\r" | tee "${goutfile}" | do_trim ++setup_qemu_logger +timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} > "$work_directory/qemu-pipe" || ret=$? fi if [ x$boot = xcoreboot ]; then @@ tests/util/grub-shell.in: fi test -n "$debug" || rm -f "${tmpfile}" "${cfgfile}" -exit 0 +rm -f "$work_directory/qemu-pipe" ++wait
[PATCH v2 03/12] grub-shell: Only show grub-mkrescue output if it returns an error
The previous behavior ignored an error and the output from grub-mkrescue. This made it a pain to discover that grub-mkrescue was the reason that tests which rely on grub-shell were failing. Even after discovering grub-mkrescue was the culprit, there was no output to indicate why it was failing. It turns out that grub-mkrescue is a thin wrapper around xorriso. So if you do not have xorriso installed it will fail with an error message about not being able to find xorriso. This change will allow grub-mkrescue output to be written to stderr, only if grub-mkrescue fails. If grub-mkrescue succeeds, there will be no output from grub-mkrescue so as not to interfere with the functioning of tests. This change should have no effect on the running of tests or other uses of grub-shell as it only modifies the error path. Also, if grub-mkrescue fails, the script exits early. Since grub-shell needs the iso image created by grub-mkresue to boot the qemu instance, a failure here should be considered fatal. Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 17 +++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 602b16f3e..9d8c417da 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -60,6 +60,17 @@ Report bugs to . EOF } +# Exec given argv and only show its output on STDERR if it returns an +# error status. +exec_show_error () { +v=`$@ 2>&1` +ret=$? +if [ "$ret" != 0 ]; then +echo "$v" >&2 +exit $ret +fi +} + . "${builddir}/grub-core/modinfo.sh" qemuopts="${GRUB_QEMU_OPTS}" serial_port=com0 @@ -383,13 +394,15 @@ if test -z "$debug"; then fi if [ x$boot != xnet ] && [ x$boot != xemu ]; then -pkgdatadir="@builddir@" "@builddir@/grub-mkrescue" "--output=${isofile}" "--override-directory=${builddir}/grub-core" \ +pkgdatadir="@builddir@" \ +exec_show_error "@builddir@/grub-mkrescue" "--output=${isofile}" \ + "--override-directory=${builddir}/grub-core" \ --rom-directory="${rom_directory}" \ --locale-directory="@srcdir@/po" \ --themes-directory="@srcdir@/themes" \ $mkimage_extra_arg ${mkrescue_args} \ "/boot/grub/grub.cfg=${cfgfile}" "/boot/grub/testcase.cfg=${source}" \ - ${files} >/dev/null 2>&1 + ${files} || exit $? fi if [ x$boot = xhd ]; then if [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm64-efi ] || [ "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = arm-efi ]; then -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 06/12] grub-shell: Add grub output logfile with grub-shell --debug
This allows seeing full qemu output of grub-shell, which can be invaluable when debugging failing tests. Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 8c6ed76d7..c6d7860e9 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -379,6 +379,9 @@ echo "${halt_cmd}" >>${cfgfile} test -z "$debug" || echo "GRUB script: ${cfgfile}" >&2 test -z "$debug" || echo "GRUB testcase script: ${tmpfile}" >&2 + +goutfile="$work_directory/grub-qemu.log" +test -z "$debug" || echo "GRUB output log: ${goutfile}" >&2 test -z "$debug" || echo "Boot device: ${boot}" >&2 isofile="$work_directory/grub.iso" @@ -502,7 +505,7 @@ if [ x$boot = xnet ]; then cp "${cfgfile}" "$netdir/boot/grub/grub.cfg" cp "${source}" "$netdir/boot/grub/testcase.cfg" [ -z "$files" ] || copy_extra_files "$netdir" $files -timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | do_trim +timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | tee "${goutfile}" | do_trim elif [ x$boot = xemu ]; then rootdir="$work_directory/rootdir" grubdir="$rootdir/boot/grub" @@ -521,11 +524,11 @@ elif [ x$boot = xemu ]; then [ -z "$files" ] || copy_extra_files "$rootdir" $files roottar="$work_directory/root.tar" (cd "$rootdir"; tar cf "$roottar" .) -@builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot/grub" | tr -d "\r" | do_trim +@builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot/grub" | tr -d "\r" | tee "${goutfile}" | do_trim test -n "$debug" || rm -rf "$rootdir" test -n "$debug" || rm -f "$roottar" else -timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} | cat | tr -d "\r" | do_trim +timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} | cat | tr -d "\r" | tee "${goutfile}" | do_trim fi if [ x$boot = xcoreboot ]; then test -n "$debug" || rm -f "${imgfile}" -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 02/12] grub-shell: Trim line should always be matched from the beginning of the line
When turning on shell tracing the trim line will be output before we actually want to start the trim. However, in this case the trim line never starts from the beginning of the line. So start trimming from the correct line by matching from the beginning of the line. Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index b409962f1..602b16f3e 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -343,7 +343,7 @@ terminal_output ${term} EOF if [ $trim = 1 ]; then -echo "echo $trim_head" >>${cfgfile} +echo "echo; echo $trim_head" >>${cfgfile} fi rom_directory=`mktemp -d "${TMPDIR:-/tmp}/tmp.XX"` || exit 1 @@ -457,7 +457,7 @@ fi do_trim () { if [ $trim = 1 ] || [ $trim = 2 ]; then - awk '{ if (have_head == 1) print $0; } /'"$trim_head"'/ { have_head=1; }' + awk '{ if (have_head == 1) print $0; } /^'"$trim_head"'/ { have_head=1; }' else cat fi -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 04/12] grub-shell: Allow setting default timeout via GRUB_SHELL_DEFAULT_TIMEOUT envvar
Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 9d8c417da..e80471126 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -211,7 +211,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in console=console;; esac -timeout=60 +timeout=${GRUB_SHELL_DEFAULT_TIMEOUT:-60} mkimage_extra_arg= # Check the arguments. -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 08/12] tests: Allow turning on shell tracing from environment variables
This allows turning on shell tracing when its not practical or not possible to use commandline arguments. Turn on tracing when the envvar is an integer greater than 1, since these can log a lot of messages. Signed-off-by: Glenn Washburn --- tests/util/grub-fs-tester.in | 2 ++ tests/util/grub-shell.in | 5 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/util/grub-fs-tester.in b/tests/util/grub-fs-tester.in index 2dcd09f5e..6b8028f9b 100644 --- a/tests/util/grub-fs-tester.in +++ b/tests/util/grub-fs-tester.in @@ -2,6 +2,8 @@ set -e +[ "${GRUB_TEST_DEFAULT_DEBUG:-0}" -gt 1 ] && set -x + fs="$1" GRUBFSTEST="@builddir@/grub-fstest" diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index f4b733858..78f27339f 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -215,6 +215,7 @@ esac timeout=${GRUB_SHELL_DEFAULT_TIMEOUT:-60} mkimage_extra_arg= +debug=${GRUB_SHELL_DEFAULT_DEBUG:-$GRUB_TEST_DEFAULT_DEBUG} # Check the arguments. for option in "$@"; do @@ -234,7 +235,7 @@ for option in "$@"; do --no-trim) trim=0 ;; --debug) -debug=1 ;; +debug=$((debug+1)) ;; --modules=*) ms=`echo "$option" | sed -e 's/--modules=//' -e 's/,/ /g'` modules="$modules $ms" ;; @@ -319,6 +320,8 @@ for option in "$@"; do esac done +[ "${debug:-0}" -gt 1 ] && set -x + if [ "x${source}" = x ] ; then tmpfile="$work_directory/testcase.cfg" while read REPLY; do -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 09/12] grub-shell: Add --verbose to mkrescue when $debug is greater than 2
Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 78f27339f..eb8f43ff2 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -404,7 +404,9 @@ fi if [ x$boot != xnet ] && [ x$boot != xemu ]; then pkgdatadir="@builddir@" \ -exec_show_error "@builddir@/grub-mkrescue" "--output=${isofile}" \ +exec_show_error "@builddir@/grub-mkrescue" \ + ${debug:+$([ "$debug" -gt 2 ] && echo -n "--verbose")} \ + "--output=${isofile}" \ "--override-directory=${builddir}/grub-core" \ --rom-directory="${rom_directory}" \ --locale-directory="@srcdir@/po" \ -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 05/12] grub-shell: Put all generated files into working dir and use better file names
When running tests there are many invocations of grub-shell, and because the output files are all random names in the same tmp directory, it becomes more work to figure out which files went with which grub-shell invocations. So all generated files from one invocation of grub-shell are put into a randomly named directory, so as not to collide with other grub-shell invocations. And now that the generated files can be put in a location where they will not get stepped on, and they can be named sensible names. Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 22 +- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index e80471126..8c6ed76d7 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -71,6 +71,8 @@ exec_show_error () { fi } +work_directory=${WORKDIR:-`mktemp -d "${TMPDIR:-/tmp}/grub-shell.XX"`} || exit 1 + . "${builddir}/grub-core/modinfo.sh" qemuopts="${GRUB_QEMU_OPTS}" serial_port=com0 @@ -80,7 +82,7 @@ pseries=n disk="hda " case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in *-emu) - device_map=`mktemp "${TMPDIR:-/tmp}/tmp.XX"` || exit 1 + device_map="$work_directory/device.map" boot=emu console=console disk=0 @@ -318,14 +320,14 @@ for option in "$@"; do done if [ "x${source}" = x ] ; then -tmpfile=`mktemp "${TMPDIR:-/tmp}/tmp.XX"` || exit 1 +tmpfile="$work_directory/testcase.cfg" while read REPLY; do echo "$REPLY" >> ${tmpfile} done source=${tmpfile} fi -cfgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XX"` || exit 1 +cfgfile="$work_directory/grub.cfg" cat <${cfgfile} grubshell=yes enable_progress_indicator=0 @@ -357,7 +359,8 @@ if [ $trim = 1 ]; then echo "echo; echo $trim_head" >>${cfgfile} fi -rom_directory=`mktemp -d "${TMPDIR:-/tmp}/tmp.XX"` || exit 1 +rom_directory="$work_directory/rom_directory" +mkdir -p "$rom_directory" for mod in ${modules} do @@ -378,7 +381,7 @@ test -z "$debug" || echo "GRUB script: ${cfgfile}" >&2 test -z "$debug" || echo "GRUB testcase script: ${tmpfile}" >&2 test -z "$debug" || echo "Boot device: ${boot}" >&2 -isofile=`mktemp "${TMPDIR:-/tmp}/tmp.XX"` || exit 1 +isofile="$work_directory/grub.iso" test -z "$debug" || echo "GRUB ISO file: ${isofile}" >&2 test -z "$debug" || echo "GRUB ROM directory: ${rom_directory}" >&2 @@ -450,7 +453,7 @@ if [ x$boot = xmips_qemu ]; then fi if [ x$boot = xcoreboot ]; then -imgfile=`mktemp "${TMPDIR:-/tmp}/tmp.XX"` || exit 1 +imgfile="$work_directory/coreboot.img" cp "${GRUB_COREBOOT_ROM}" "${imgfile}" "${GRUB_CBFSTOOL}" "${imgfile}" add-payload -f "${rom_directory}/coreboot.elf" -n fallback/payload bootdev="-bios ${imgfile}" @@ -493,14 +496,15 @@ copy_extra_files() { } if [ x$boot = xnet ]; then -netdir=`mktemp -d "${TMPDIR:-/tmp}/tmp.XX"` || exit 1 +netdir="$work_directory/netdir" +mkdir -p "$netdir" pkgdatadir="@builddir@" "@builddir@/grub-mknetdir" "--grub-mkimage=${builddir}/grub-mkimage" "--directory=${builddir}/grub-core" "--net-directory=$netdir" ${mkrescue_args} > /dev/null cp "${cfgfile}" "$netdir/boot/grub/grub.cfg" cp "${source}" "$netdir/boot/grub/testcase.cfg" [ -z "$files" ] || copy_extra_files "$netdir" $files timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | do_trim elif [ x$boot = xemu ]; then -rootdir="$(mktemp -d "${TMPDIR:-/tmp}/tmp.XX")" +rootdir="$work_directory/rootdir" grubdir="$rootdir/boot/grub" mkdir -p "$grubdir/fonts" mkdir -p "$grubdir/themes" @@ -515,7 +519,7 @@ elif [ x$boot = xemu ]; then cp "${cfgfile}" "$grubdir/grub.cfg" cp "${source}" "$grubdir/testcase.cfg" [ -z "$files" ] || copy_extra_files "$rootdir" $files -roottar="$(mktemp "${TMPDIR:-/tmp}/tmp.XX")" +roottar="$work_directory/root.tar" (cd "$rootdir"; tar cf "$roottar" .) @builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot/grub" | tr -d "\r" | do_trim test -n "$debug" || rm -rf "$rootdir" -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 12/12] grub-shell: Add flexibility in QEMU firmware handling
The current qemu firmware paths for arm-efi and arm64-efi are not available on Ubuntu/Debian but are hardcoded. Switch to first looking for firmware files in the source directory and if not found, look for them in locations where Debian installs them. Prefer to use the firmware file usable with the QEMU '-bios' option and if not found use the newer pflash firmware files. This allows supporting older systems more easily. By looking for files in the source directory first, system firmware files can be overridden and it can be ensured that the tests can be run regardless of the distro and where it stores firmware files. If no firmware files are found, print an error message telling the user that those files must exist and exit with error. Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 95 ++-- 1 file changed, 91 insertions(+), 4 deletions(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index e56506444..5d7926c94 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -180,21 +180,86 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in boot=cd console=console trim=1 - qemuopts="-bios OVMF-ia32.fd $qemuopts" + bios=${srcdir}/OVMF32.fd + pflash_code=${srcdir}/OVMF32_CODE.fd + pflash_vars=${srcdir}/OVMF32_VARS.fd + if [ -f "$bios" ]; then + qemuopts="-bios $bios $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_vars $qemuopts" + else + bios=/usr/share/qemu/OVMF32.fd + pflash_code=/usr/share/OVMF/OVMF32_CODE_4M.secboot.fd + pflash_vars=/usr/share/OVMF/OVMF32_VARS_4M.fd + if [ -f "$bios" ]; then + qemuopts="-bios $bios $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_vars $qemuopts" + else + echo "Firmware not found, please make sure $bios or both $pflash_code and $pflash_vars exist." >&2 + exit 1 + fi + fi + qemuopts="-machine q35,accel=tcg $qemuopts" ;; x86_64-efi) qemu=qemu-system-x86_64 boot=cd console=console trim=1 - qemuopts="-bios OVMF.fd $qemuopts" + bios=${srcdir}/OVMF.fd + pflash_code=${srcdir}/OVMF_CODE.fd + pflash_vars=${srcdir}/OVMF_VARS.fd + if [ -f "$bios" ]; then + qemuopts="-bios $bios $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_vars $qemuopts" + else + bios=/usr/share/qemu/OVMF.fd + pflash_code=/usr/share/OVMF/OVMF_CODE.fd + pflash_vars=/usr/share/OVMF/OVMF_VARS.fd + if [ -f "$bios" ]; then + qemuopts="-bios $bios $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_vars $qemuopts" + else + echo "Firmware not found, please make sure $bios or both $pflash_code and $pflash_vars exist." >&2 + exit 1 + fi + fi ;; arm64-efi) qemu=qemu-system-aarch64 boot=hd console=console trim=1 - qemuopts="-machine virt -cpu cortex-a57 -bios /usr/share/qemu-efi/QEMU_EFI.fd $qemuopts" + bios=${srcdir}/AAVMF.fd + pflash_code=${srcdir}/AAVMF_CODE.fd + pflash_vars=${srcdir}/AAVMF_VARS.fd + if [ -f "$bios" ]; then + qemuopts="-bios $bios $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_vars $qemuopts" + else + bios=/usr/share/qemu-efi-aarch64/QEMU_EFI.fd + pflash_code=/usr/share/AAVMF/AAVMF_CODE.fd + pflash_vars=/usr/share/AAVMF/AAVMF_VARS.fd + if [ -f "$bios" ]; then + qemuopts="-bios $bios $qemuopts" + elif [ -f "$pflash_code" ]; then + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_code $qemuopts" + qemuopts="-drive if=pflash,format=raw,readonly=on,file=$pflash_vars $qemuopts" + else + echo "Firmware not found, please make sure $bios or both $pflash_code and $pflash_vars exist." >&2 + exit 1 + fi + fi + qemuopts="-machi
[PATCH v2 11/12] grub-shell: Use malta qemu-mips machine type instead off non-existant indy
Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index 180917c52..e56506444 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -119,7 +119,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in mips-arc) boot=cd qemu=qemu-system-mips64 - qemuopts="-M indy $qemuopts" + qemuopts="-M malta $qemuopts" serial_port=arc/serial0/line0 console= trim=1 -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 07/12] grub-shell: Set exit status to qemu exit status
This allows us to test if unexpected output in test scripts is because of a bug in grub, because there was an error in qemu, or qemu was killed due to a timeout. Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 19 +++ 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index c6d7860e9..f4b733858 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -498,6 +498,12 @@ copy_extra_files() { done } +setup_qemu_logger() { +cat < "$work_directory/qemu-pipe" | tr -d "\r" | tee "${goutfile}" | do_trim & +} + +ret=0 +mkfifo "$work_directory/qemu-pipe" if [ x$boot = xnet ]; then netdir="$work_directory/netdir" mkdir -p "$netdir" @@ -505,7 +511,8 @@ if [ x$boot = xnet ]; then cp "${cfgfile}" "$netdir/boot/grub/grub.cfg" cp "${source}" "$netdir/boot/grub/testcase.cfg" [ -z "$files" ] || copy_extra_files "$netdir" $files -timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic | cat | tr -d "\r" | tee "${goutfile}" | do_trim +setup_qemu_logger +timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -boot n -net "user,tftp=$netdir,bootfile=/boot/grub/${grub_modinfo_target_cpu}-${grub_modinfo_platform}/core.$netbootext" -net nic > "$work_directory/qemu-pipe" || ret=$? elif [ x$boot = xemu ]; then rootdir="$work_directory/rootdir" grubdir="$rootdir/boot/grub" @@ -524,11 +531,13 @@ elif [ x$boot = xemu ]; then [ -z "$files" ] || copy_extra_files "$rootdir" $files roottar="$work_directory/root.tar" (cd "$rootdir"; tar cf "$roottar" .) -@builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot/grub" | tr -d "\r" | tee "${goutfile}" | do_trim +setup_qemu_logger +@builddir@/grub-core/grub-emu -m "$device_map" --memdisk "$roottar" -r memdisk -d "/boot/grub" > "$work_directory/qemu-pipe" || ret=$? test -n "$debug" || rm -rf "$rootdir" test -n "$debug" || rm -f "$roottar" else -timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} | cat | tr -d "\r" | tee "${goutfile}" | do_trim +setup_qemu_logger +timeout -s KILL $timeout "${qemu}" ${qemuopts} ${serial_null} -serial file:/dev/stdout -${device}"${isofile}" ${bootdev} > "$work_directory/qemu-pipe" || ret=$? fi if [ x$boot = xcoreboot ]; then test -n "$debug" || rm -f "${imgfile}" @@ -536,6 +545,8 @@ fi test -n "$debug" || rm -f "${isofile}" test -n "$debug" || rm -rf "${rom_directory}" test -n "$debug" || rm -f "${tmpfile}" "${cfgfile}" -exit 0 +rm -f "$work_directory/qemu-pipe" +wait +exit $ret -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v2 10/12] grub-shell: Only turn on qemu head when large debug value is specified
There are several levels of debug and more may be added. But the qemu head should be one of the highest debug levels. Set debug to a high value of 10 to turn on the head. We do not want to accidentally turn it on when adding a new debug level to the testing system. Signed-off-by: Glenn Washburn --- tests/util/grub-shell.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/util/grub-shell.in b/tests/util/grub-shell.in index eb8f43ff2..180917c52 100644 --- a/tests/util/grub-shell.in +++ b/tests/util/grub-shell.in @@ -391,7 +391,7 @@ isofile="$work_directory/grub.iso" test -z "$debug" || echo "GRUB ISO file: ${isofile}" >&2 test -z "$debug" || echo "GRUB ROM directory: ${rom_directory}" >&2 -if test -z "$debug"; then +if test "${debug:-0}" -lt 10; then qemuopts="${qemuopts} -nographic -monitor file:/dev/null" # SeaBIOS 1.11.0 added support for VGA emulation over a serial port. If # this is configured in SeaBIOS, then -nographic causes some extra junk to -- 2.27.0 ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel
[PATCH v4] misc: Allow selective disabling of debug facility names
Sometimes you only know which debug logging facility names you want to turn off, not necessarily all the ones you want enabled. This patch allows the debug string to contain facility names in the $debug variable which are prefixed with a "-" to disable debug log messages for that conditional. Say you want all debug logging on except for btrfs and scripting, then do: "set debug=all,-btrfs,-scripting" Note, that only the last occurence of the facility name with or without a leading "-" is considered. So simply appending ",-facilityname" to the $debug variable will disable that conditional. To illustrate, the command "set debug=all,-btrfs,-scripting,btrfs" will enable btrfs. Also, add documentation explaining this new behavior. Signed-off-by: Glenn Washburn --- Range-diff against v3: 1: 31439a7fb ! 1: b5165ba45 misc: Allow selective disabling of debug facility names @@ Metadata ## Commit message ## misc: Allow selective disabling of debug facility names -Sometimes you know only know which debug logging facility names you want to +Sometimes you only know which debug logging facility names you want to turn off, not necessarily all the ones you want enabled. This patch allows the debug string to contain facility names in the $debug variable which are prefixed with a "-" to disable debug log messages for that conditional. Say @@ docs/grub.texi: processed by commands @command{configfile} (@pxref{configfile}) -whitespace or @samp{,}, or @samp{all} to enable all available debugging -output. The facility names are the first argument to grub_dprintf. Consult +of GRUB. The value is an ordered list of debug facility names separated by -+whitespace or @samp{,}. If the special facility names @samp{all} is present ++whitespace or @samp{,}. If the special facility named @samp{all} is present +then debugging output of all facility names is enabled at the start of +processing the value of this variable. A facility's debug output can then be +disabled by prefixing its name with a @samp{-}. The last occurence facility @@ grub-core/kern/misc.c: __attribute__ ((alias("grub_printf"))); + continue; + + /* -+ * If found condition is at the start of debug, then enable debug. Else -+ * if found condition is prefixed with '-' and the start is on a word -+ * boundary, then disable debug. Otherwise, if the start is on a word -+ * boundary, enable debug. If none of these cases, ignore. ++ * If found condition is at the start of debug or the start is on a word ++ * boundary, then enable debug. Else if found condition is prefixed with ++ * '-' and the start is on a word boundary, then disable debug. If none ++ * of these cases, ignore. + */ -+ if (found == debug) ++ if (found == debug || *(found - 1) == ',' || grub_isspace (*(found - 1))) + ret = 1; -+ else if (*(found-1) == '-' && ((found == debug + 1) || (*(found-2) == ',' -+ || grub_isspace (*(found-2) ++ else if (*(found - 1) == '-' && ((found == debug + 1) || (*(found - 2) == ',' ++ || grub_isspace (*(found - 2) + ret = 0; -+ else if (*(found-1) == ',' || grub_isspace (*(found-1))) -+ ret = 1; +} + + return ret; docs/grub.texi| 13 ++--- grub-core/kern/misc.c | 41 + 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/docs/grub.texi b/docs/grub.texi index 99d0a0149..22efbd297 100644 --- a/docs/grub.texi +++ b/docs/grub.texi @@ -3388,9 +3388,16 @@ processed by commands @command{configfile} (@pxref{configfile}) or @command{norm @subsection debug This variable may be set to enable debugging output from various components -of GRUB. The value is a list of debug facility names separated by -whitespace or @samp{,}, or @samp{all} to enable all available debugging -output. The facility names are the first argument to grub_dprintf. Consult +of GRUB. The value is an ordered list of debug facility names separated by +whitespace or @samp{,}. If the special facility named @samp{all} is present +then debugging output of all facility names is enabled at the start of +processing the value of this variable. A facility's debug output can then be +disabled by prefixing its name with a @samp{-}. The last occurence facility +name with or without a leading @samp{-} takes precendent over any previous +occurence. This allows the easy enabling or disabling of facilities by +appending a @samp{,} and then the facility name with or without the leading +@samp{-}, which will preserve the state of the rest of the facilities. +The facility names are the first argument to grub_dprintf. Consult the source for more details. diff --git a/grub-core/kern
[PATCH v8 0/7] Cryptodisk detached headers and key files
‐‐‐ Original Message ‐‐‐ On Sunday, January 2nd, 2022 at 3:52 AM, Glenn Washburn wrote: > This patch series is an updated version of the v7 sent by Denis Carikli with > > modifications to reflect changes in argument passing to crypto backends. The > > previous patch #6 titled "Add support for LUKS1 key files" has been removed > > as its not needed anymore. Patches #6 and #7 are new, for updating the > > cryptomount help string and adding support for detached headers in the LUKS2 > > crypto backend, respectively. > > I modified the commit tags from v7 as seemed appropriate to me, but they may > > not be desirable as-is. > > Glenn > Thanks for updating these patches. I remember several attempts to introduce detached headers/keyfile in recent years and didn't believe it was going to happen anytime soon. Hope these patches will be merged in the next grub release. Best regards, Maxim Fomin ___ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel