[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v4 14/15] luks2: Better error handling when setting up the cr
From: |
Patrick Steinhardt |
Subject: |
Re: [PATCH v4 14/15] luks2: Better error handling when setting up the cryptodisk. |
Date: |
Sun, 15 Nov 2020 11:13:04 +0100 |
On Fri, Nov 06, 2020 at 10:44:34PM -0600, Glenn Washburn wrote:
> Signed-off-by: Glenn Washburn <development@efficientek.com>
A commit message would help to set the stage for your changes here,
especially so as they're non-trivial.
> ---
> grub-core/disk/luks2.c | 70 +++++++++++++++++++++++++++++++++++++++---
> include/grub/misc.h | 2 ++
> 2 files changed, 67 insertions(+), 5 deletions(-)
>
> diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> index 4a4a0dec4..751b48d6a 100644
> --- a/grub-core/disk/luks2.c
> +++ b/grub-core/disk/luks2.c
> @@ -600,9 +600,16 @@ luks2_recover_key (grub_disk_t source,
> goto err;
> }
>
> + if (source->total_sectors == GRUB_DISK_SIZE_UNKNOWN)
> + {
> + ret = grub_error (GRUB_ERR_BUG, "not a luks2 device");
> + goto err;
> + }
> +
> /* Try all keyslot */
> for (i = 0; i < size; i++)
> {
> + grub_errno = GRUB_ERR_NONE;
> ret = luks2_get_keyslot (&keyslot, &digest, &segment, json, i);
> if (ret)
> goto err;
> @@ -617,13 +624,66 @@ luks2_recover_key (grub_disk_t source,
>
> /* Set up disk according to keyslot's segment. */
> crypt->offset_sectors = grub_divmod64 (segment.offset,
> segment.sector_size, NULL);
> - crypt->log_sector_size = sizeof (unsigned int) * 8
> - - __builtin_clz ((unsigned int) segment.sector_size) - 1;
> + crypt->log_sector_size = grub_log2ull (segment.sector_size);
> if (grub_strcmp (segment.size, "dynamic") == 0)
> - crypt->total_sectors = (grub_disk_get_size (source) >>
> (crypt->log_sector_size - source->log_sector_size))
> - - crypt->offset_sectors;
> + {
> + /* Convert source sized number of sectors to cryptodisk sized sectors
> */
> + crypt->total_sectors = source->total_sectors >>
> (crypt->log_sector_size - source->log_sector_size);
> + if (crypt->total_sectors < crypt->offset_sectors)
> + {
> + grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\" offset"
> + " is greater than disk size.",
> + segment.slot_key);
> + continue;
> + }
> +
> + crypt->total_sectors -= crypt->offset_sectors;
> + }
> else
> - crypt->total_sectors = grub_strtoull (segment.size, NULL, 10) >>
> crypt->log_sector_size;
> + {
> + crypt->total_sectors = grub_strtoull (segment.size, NULL, 10) >>
> crypt->log_sector_size;
> + if (grub_errno == GRUB_ERR_NONE)
> + ;
If any other code previously ran which set `grub_errno`, then it would
still carry the old error value here as `grub_strtoull` doesn't unset it
if no error occurred. We'd thus have to first set `grub_errno =
GRUB_ERR_NONE` before the call to `grub_strtoull`.
Patrick
> + else if(grub_errno == GRUB_ERR_BAD_NUMBER)
> + {
> + /* TODO: Unparsable number-string, try to use the whole disk */
> + grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\" size"
> + " is not a parsable number.",
> + segment.slot_key);
> + continue;
> + }
> + else if(grub_errno == GRUB_ERR_OUT_OF_RANGE)
> + {
> + /* There was an overflow in parsing segment.size, so disk must
> + * be very large or the string is incorrect. */
> + if ((source->total_sectors
> + >> (crypt->log_sector_size - source->log_sector_size))
> + > crypt->total_sectors)
> + {
> + grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\""
> + " size is very large. The end may be"
> + " inaccessible.",
> + segment.slot_key);
> + }
> + else
> + {
> + /* FIXME: Set total_sectors as in "dynamic" case. */
> + grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\""
> + " size greater than the source"
> + " device.",
> + segment.slot_key);
> + continue;
> + }
> + }
> + }
> +
> + if (crypt->total_sectors == 0)
> + {
> + grub_dprintf ("luks2", "Segment \"%"PRIuGRUB_UINT64_T"\" has"
> + " zero sectors, skipping.",
> + segment.slot_key);
> + continue;
> + }
>
> ret = luks2_decrypt_key (candidate_key, source, crypt, &keyslot,
> (const grub_uint8_t *) passphrase, grub_strlen
> (passphrase));
> diff --git a/include/grub/misc.h b/include/grub/misc.h
> index b7ca6dd58..ec25131ba 100644
> --- a/include/grub/misc.h
> +++ b/include/grub/misc.h
> @@ -481,5 +481,7 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file,
>
> #define grub_max(a, b) (((a) > (b)) ? (a) : (b))
> #define grub_min(a, b) (((a) < (b)) ? (a) : (b))
> +#define grub_log2ull(n) (GRUB_TYPE_BITS (grub_uint64_t) \
> + - __builtin_clzll (n) - 1)
>
> #endif /* ! GRUB_MISC_HEADER */
> --
> 2.27.0
>
signature.asc
Description: PGP signature
[PATCH v4 15/15] luks2: Error check segment.sector_size., Glenn Washburn, 2020/11/06
Re: [PATCH v4 00/15] Cryptodisk fixes for v2.06 redux, Daniel Kiper, 2020/11/17
[PATCH v5 00/11] Cryptodisk fixes for v2.06 redux, Glenn Washburn, 2020/11/23