All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 0/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner
@ 2022-08-11 17:48 Glenn Washburn
  2022-08-11 17:48 ` [PATCH v5 1/2] misc: Add cast in grub_strncasecmp() to drop sign when calling grub_tolower() Glenn Washburn
  2022-08-11 17:48 ` [PATCH v5 2/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner Glenn Washburn
  0 siblings, 2 replies; 6+ messages in thread
From: Glenn Washburn @ 2022-08-11 17:48 UTC (permalink / raw)
  To: grub-devel, Daniel Kiper; +Cc: Patrick Steinhardt, Glenn Washburn

Updates since v4:
 * Add patch to add missing casts to grub_strncasecmp()
 * Remove patch forcing null termination of uuid from header
 * Use correct patch for uuid comparison. The previous had bad
   variable name usage, but the logic is the same.

Glenn

Glenn Washburn (2):
  misc: Add cast in grub_strncasecmp() to drop sign when calling
    grub_tolower()
  cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner

 grub-core/disk/cryptodisk.c |  4 ++--
 grub-core/disk/geli.c       |  2 +-
 grub-core/disk/luks.c       | 21 ++++-----------------
 grub-core/disk/luks2.c      | 15 ++++-----------
 include/grub/misc.h         | 31 ++++++++++++++++++++++++++++++-
 5 files changed, 41 insertions(+), 32 deletions(-)

-- 
2.34.1



^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH v5 1/2] misc: Add cast in grub_strncasecmp() to drop sign when calling grub_tolower()
  2022-08-11 17:48 [PATCH v5 0/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner Glenn Washburn
@ 2022-08-11 17:48 ` Glenn Washburn
  2022-08-19 16:51   ` Daniel Kiper
  2022-08-11 17:48 ` [PATCH v5 2/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner Glenn Washburn
  1 sibling, 1 reply; 6+ messages in thread
From: Glenn Washburn @ 2022-08-11 17:48 UTC (permalink / raw)
  To: grub-devel, Daniel Kiper; +Cc: Patrick Steinhardt, Glenn Washburn

Note this cast was fixed in grub_strcasecmp() in commit ce41ab7aab
(* grub-core/kern/misc.c (grub_strcmp): Use unsigned comparison as per
common usage and preffered in several parts of code.), but this commit
omitted fixing it in grub_strncasecmp().

Signed-off-by: Glenn Washburn <development@efficientek.com>
---
 include/grub/misc.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/grub/misc.h b/include/grub/misc.h
index 776dbf8af..1c25c1767 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -232,7 +232,8 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
 
   while (*s1 && *s2 && --n)
     {
-      if (grub_tolower (*s1) != grub_tolower (*s2))
+      if (grub_tolower ((grub_uint8_t) *s1)
+	  != grub_tolower ((grub_uint8_t) *s2))
 	break;
 
       s1++;
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v5 2/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner
  2022-08-11 17:48 [PATCH v5 0/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner Glenn Washburn
  2022-08-11 17:48 ` [PATCH v5 1/2] misc: Add cast in grub_strncasecmp() to drop sign when calling grub_tolower() Glenn Washburn
@ 2022-08-11 17:48 ` Glenn Washburn
  2022-08-15 15:28   ` Patrick Steinhardt
  1 sibling, 1 reply; 6+ messages in thread
From: Glenn Washburn @ 2022-08-11 17:48 UTC (permalink / raw)
  To: grub-devel, Daniel Kiper; +Cc: Patrick Steinhardt, Glenn Washburn

A user can now specify UUID strings with dashes, instead of having to remove
dashes. This is backwards-compatability preserving and also fixes a source
of user confusion over the inconsistency with how UUIDs are specified
between file system UUIDs and cryptomount UUIDs. Since cryptsetup, the
reference implementation for LUKS, displays and generates UUIDs with dashes
there has been additional confusion when using the UUID strings from
cryptsetup as exact input into GRUB does not find the expected cryptodisk.

A new function grub_uuidcasecmp is added that is general enough to be used
other places where UUIDs are being compared.

Signed-off-by: Glenn Washburn <development@efficientek.com>
---
 grub-core/disk/cryptodisk.c |  4 ++--
 grub-core/disk/geli.c       |  2 +-
 grub-core/disk/luks.c       | 21 ++++-----------------
 grub-core/disk/luks2.c      | 15 ++++-----------
 include/grub/misc.h         | 28 ++++++++++++++++++++++++++++
 5 files changed, 39 insertions(+), 31 deletions(-)

diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
index f1fe0d390..00d66ab02 100644
--- a/grub-core/disk/cryptodisk.c
+++ b/grub-core/disk/cryptodisk.c
@@ -701,7 +701,7 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk)
   if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0)
     {
       for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
-	if (grub_strcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid) == 0)
+	if (grub_uuidcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid, sizeof (dev->uuid)) == 0)
 	  break;
     }
   else
@@ -928,7 +928,7 @@ grub_cryptodisk_get_by_uuid (const char *uuid)
 {
   grub_cryptodisk_t dev;
   for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
-    if (grub_strcasecmp (dev->uuid, uuid) == 0)
+    if (grub_uuidcasecmp (dev->uuid, uuid, sizeof (dev->uuid)) == 0)
       return dev;
   return NULL;
 }
diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
index e190066f9..722910d64 100644
--- a/grub-core/disk/geli.c
+++ b/grub-core/disk/geli.c
@@ -305,7 +305,7 @@ geli_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
       return NULL;
     }
 
-  if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
+  if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, uuid, sizeof (uuid)) != 0)
     {
       grub_dprintf ("geli", "%s != %s\n", uuid, cargs->search_uuid);
       return NULL;
diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
index 7f837d52c..9e1e6a5d9 100644
--- a/grub-core/disk/luks.c
+++ b/grub-core/disk/luks.c
@@ -66,10 +66,7 @@ static grub_cryptodisk_t
 luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
 {
   grub_cryptodisk_t newdev;
-  const char *iptr;
   struct grub_luks_phdr header;
-  char *optr;
-  char uuid[sizeof (header.uuid) + 1];
   char ciphername[sizeof (header.cipherName) + 1];
   char ciphermode[sizeof (header.cipherMode) + 1];
   char hashspec[sizeof (header.hashSpec) + 1];
@@ -92,19 +89,9 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
       || grub_be_to_cpu16 (header.version) != 1)
     return NULL;
 
-  grub_memset (uuid, 0, sizeof (uuid));
-  optr = uuid;
-  for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)];
-       iptr++)
+  if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, header.uuid, sizeof (header.uuid)) != 0)
     {
-      if (*iptr != '-')
-	*optr++ = *iptr;
-    }
-  *optr = 0;
-
-  if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
-    {
-      grub_dprintf ("luks", "%s != %s\n", uuid, cargs->search_uuid);
+      grub_dprintf ("luks", "%s != %s\n", header.uuid, cargs->search_uuid);
       return NULL;
     }
 
@@ -123,7 +110,7 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
   newdev->source_disk = NULL;
   newdev->log_sector_size = GRUB_LUKS1_LOG_SECTOR_SIZE;
   newdev->total_sectors = grub_disk_native_sectors (disk) - newdev->offset_sectors;
-  grub_memcpy (newdev->uuid, uuid, sizeof (uuid));
+  grub_memcpy (newdev->uuid, header.uuid, sizeof (header.uuid));
   newdev->modname = "luks";
 
   /* Configure the hash used for the AF splitter and HMAC.  */
@@ -143,7 +130,7 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
       return NULL;
     }
 
-  COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
+  COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (header.uuid));
   return newdev;
 }
 
diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
index bf741d70f..ac3ab095c 100644
--- a/grub-core/disk/luks2.c
+++ b/grub-core/disk/luks2.c
@@ -350,8 +350,6 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
 {
   grub_cryptodisk_t cryptodisk;
   grub_luks2_header_t header;
-  char uuid[sizeof (header.uuid) + 1];
-  grub_size_t i, j;
 
   if (cargs->check_boot)
     return NULL;
@@ -362,14 +360,9 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
       return NULL;
     }
 
-  for (i = 0, j = 0; i < sizeof (header.uuid); i++)
-    if (header.uuid[i] != '-')
-      uuid[j++] = header.uuid[i];
-  uuid[j] = '\0';
-
-  if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
+  if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, header.uuid, sizeof (header.uuid)) != 0)
     {
-      grub_dprintf ("luks2", "%s != %s\n", uuid, cargs->search_uuid);
+      grub_dprintf ("luks2", "%s != %s\n", header.uuid, cargs->search_uuid);
       return NULL;
     }
 
@@ -377,8 +370,8 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
   if (!cryptodisk)
     return NULL;
 
-  COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (uuid));
-  grub_memcpy (cryptodisk->uuid, uuid, sizeof (uuid));
+  COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (header.uuid));
+  grub_memcpy (cryptodisk->uuid, header.uuid, sizeof (header.uuid));
 
   cryptodisk->modname = "luks2";
   return cryptodisk;
diff --git a/include/grub/misc.h b/include/grub/misc.h
index 1c25c1767..2ed378188 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -244,6 +244,34 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
     - (int) grub_tolower ((grub_uint8_t) *s2);
 }
 
+/* Do a case insensitive compare of two UUID strings by ignoring all dashes */
+static inline int
+grub_uuidcasecmp (const char *uuid1, const char *uuid2, grub_size_t n)
+{
+  if (n == 0)
+    return 0;
+
+  while (*uuid1 && *uuid2 && --n)
+    {
+      /* Skip forward to non-dash on both UUIDs. */
+      while ('-' == *uuid1)
+        ++uuid1;
+
+      while ('-' == *uuid2)
+        ++uuid2;
+
+      if (grub_tolower ((grub_uint8_t) *uuid1)
+	  != grub_tolower ((grub_uint8_t) *uuid2))
+	break;
+
+      uuid1++;
+      uuid2++;
+    }
+
+  return (int) grub_tolower ((grub_uint8_t) *uuid1)
+    - (int) grub_tolower ((grub_uint8_t) *uuid2);
+}
+
 /*
  * Note that these differ from the C standard's definitions of strtol,
  * strtoul(), and strtoull() by the addition of two const qualifiers on the end
-- 
2.34.1



^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v5 2/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner
  2022-08-11 17:48 ` [PATCH v5 2/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner Glenn Washburn
@ 2022-08-15 15:28   ` Patrick Steinhardt
  2022-08-15 20:28     ` Glenn Washburn
  0 siblings, 1 reply; 6+ messages in thread
From: Patrick Steinhardt @ 2022-08-15 15:28 UTC (permalink / raw)
  To: Glenn Washburn; +Cc: grub-devel, Daniel Kiper

[-- Attachment #1: Type: text/plain, Size: 8323 bytes --]

On Thu, Aug 11, 2022 at 12:48:43PM -0500, Glenn Washburn wrote:
> A user can now specify UUID strings with dashes, instead of having to remove
> dashes. This is backwards-compatability preserving and also fixes a source
> of user confusion over the inconsistency with how UUIDs are specified
> between file system UUIDs and cryptomount UUIDs. Since cryptsetup, the
> reference implementation for LUKS, displays and generates UUIDs with dashes
> there has been additional confusion when using the UUID strings from
> cryptsetup as exact input into GRUB does not find the expected cryptodisk.
> 
> A new function grub_uuidcasecmp is added that is general enough to be used
> other places where UUIDs are being compared.
> 
> Signed-off-by: Glenn Washburn <development@efficientek.com>
> ---
>  grub-core/disk/cryptodisk.c |  4 ++--
>  grub-core/disk/geli.c       |  2 +-
>  grub-core/disk/luks.c       | 21 ++++-----------------
>  grub-core/disk/luks2.c      | 15 ++++-----------
>  include/grub/misc.h         | 28 ++++++++++++++++++++++++++++
>  5 files changed, 39 insertions(+), 31 deletions(-)
> 
> diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
> index f1fe0d390..00d66ab02 100644
> --- a/grub-core/disk/cryptodisk.c
> +++ b/grub-core/disk/cryptodisk.c
> @@ -701,7 +701,7 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk)
>    if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0)
>      {
>        for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
> -	if (grub_strcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid) == 0)
> +	if (grub_uuidcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid, sizeof (dev->uuid)) == 0)
>  	  break;
>      }
>    else
> @@ -928,7 +928,7 @@ grub_cryptodisk_get_by_uuid (const char *uuid)
>  {
>    grub_cryptodisk_t dev;
>    for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
> -    if (grub_strcasecmp (dev->uuid, uuid) == 0)
> +    if (grub_uuidcasecmp (dev->uuid, uuid, sizeof (dev->uuid)) == 0)
>        return dev;
>    return NULL;
>  }
> diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
> index e190066f9..722910d64 100644
> --- a/grub-core/disk/geli.c
> +++ b/grub-core/disk/geli.c
> @@ -305,7 +305,7 @@ geli_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
>        return NULL;
>      }
>  
> -  if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
> +  if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, uuid, sizeof (uuid)) != 0)
>      {
>        grub_dprintf ("geli", "%s != %s\n", uuid, cargs->search_uuid);
>        return NULL;
> diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
> index 7f837d52c..9e1e6a5d9 100644
> --- a/grub-core/disk/luks.c
> +++ b/grub-core/disk/luks.c
> @@ -66,10 +66,7 @@ static grub_cryptodisk_t
>  luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
>  {
>    grub_cryptodisk_t newdev;
> -  const char *iptr;
>    struct grub_luks_phdr header;
> -  char *optr;
> -  char uuid[sizeof (header.uuid) + 1];
>    char ciphername[sizeof (header.cipherName) + 1];
>    char ciphermode[sizeof (header.cipherMode) + 1];
>    char hashspec[sizeof (header.hashSpec) + 1];
> @@ -92,19 +89,9 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
>        || grub_be_to_cpu16 (header.version) != 1)
>      return NULL;
>  
> -  grub_memset (uuid, 0, sizeof (uuid));
> -  optr = uuid;
> -  for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)];
> -       iptr++)
> +  if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, header.uuid, sizeof (header.uuid)) != 0)
>      {
> -      if (*iptr != '-')
> -	*optr++ = *iptr;
> -    }
> -  *optr = 0;
> -
> -  if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
> -    {
> -      grub_dprintf ("luks", "%s != %s\n", uuid, cargs->search_uuid);
> +      grub_dprintf ("luks", "%s != %s\n", header.uuid, cargs->search_uuid);
>        return NULL;
>      }
>  
> @@ -123,7 +110,7 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
>    newdev->source_disk = NULL;
>    newdev->log_sector_size = GRUB_LUKS1_LOG_SECTOR_SIZE;
>    newdev->total_sectors = grub_disk_native_sectors (disk) - newdev->offset_sectors;
> -  grub_memcpy (newdev->uuid, uuid, sizeof (uuid));
> +  grub_memcpy (newdev->uuid, header.uuid, sizeof (header.uuid));
>    newdev->modname = "luks";
>  
>    /* Configure the hash used for the AF splitter and HMAC.  */
> @@ -143,7 +130,7 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
>        return NULL;
>      }
>  
> -  COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
> +  COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (header.uuid));
>    return newdev;
>  }
>  
> diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> index bf741d70f..ac3ab095c 100644
> --- a/grub-core/disk/luks2.c
> +++ b/grub-core/disk/luks2.c
> @@ -350,8 +350,6 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
>  {
>    grub_cryptodisk_t cryptodisk;
>    grub_luks2_header_t header;
> -  char uuid[sizeof (header.uuid) + 1];
> -  grub_size_t i, j;
>  
>    if (cargs->check_boot)
>      return NULL;
> @@ -362,14 +360,9 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
>        return NULL;
>      }
>  
> -  for (i = 0, j = 0; i < sizeof (header.uuid); i++)
> -    if (header.uuid[i] != '-')
> -      uuid[j++] = header.uuid[i];
> -  uuid[j] = '\0';
> -
> -  if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
> +  if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, header.uuid, sizeof (header.uuid)) != 0)
>      {
> -      grub_dprintf ("luks2", "%s != %s\n", uuid, cargs->search_uuid);
> +      grub_dprintf ("luks2", "%s != %s\n", header.uuid, cargs->search_uuid);
>        return NULL;
>      }
>  
> @@ -377,8 +370,8 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
>    if (!cryptodisk)
>      return NULL;
>  
> -  COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (uuid));
> -  grub_memcpy (cryptodisk->uuid, uuid, sizeof (uuid));
> +  COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (header.uuid));
> +  grub_memcpy (cryptodisk->uuid, header.uuid, sizeof (header.uuid));
>  
>    cryptodisk->modname = "luks2";
>    return cryptodisk;
> diff --git a/include/grub/misc.h b/include/grub/misc.h
> index 1c25c1767..2ed378188 100644
> --- a/include/grub/misc.h
> +++ b/include/grub/misc.h
> @@ -244,6 +244,34 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
>      - (int) grub_tolower ((grub_uint8_t) *s2);
>  }
>  
> +/* Do a case insensitive compare of two UUID strings by ignoring all dashes */
> +static inline int
> +grub_uuidcasecmp (const char *uuid1, const char *uuid2, grub_size_t n)

Nit: I find it a bit unclear with how `n` is supposed to be used. You
might expect it to denote the maximum length of either of the UUIDs, but
it's not really given that you skip over dashes without decrementing it.
So this rather looks like the "length of non-dash characters in either
of the UUIDs", which is likely not all that useful to the caller.

We should either clearly document the intent of this parameter, or make
it more useful by e.g. allowing the caller to pass both a `uuid1len` and
`uuid2len`, which get properly decremented when skipping over dashes.

Patrick

> +{
> +  if (n == 0)
> +    return 0;
> +
> +  while (*uuid1 && *uuid2 && --n)
> +    {
> +      /* Skip forward to non-dash on both UUIDs. */
> +      while ('-' == *uuid1)
> +        ++uuid1;
> +
> +      while ('-' == *uuid2)
> +        ++uuid2;
> +
> +      if (grub_tolower ((grub_uint8_t) *uuid1)
> +	  != grub_tolower ((grub_uint8_t) *uuid2))
> +	break;
> +
> +      uuid1++;
> +      uuid2++;
> +    }
> +
> +  return (int) grub_tolower ((grub_uint8_t) *uuid1)
> +    - (int) grub_tolower ((grub_uint8_t) *uuid2);
> +}
> +
>  /*
>   * Note that these differ from the C standard's definitions of strtol,
>   * strtoul(), and strtoull() by the addition of two const qualifiers on the end
> -- 
> 2.34.1
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v5 2/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner
  2022-08-15 15:28   ` Patrick Steinhardt
@ 2022-08-15 20:28     ` Glenn Washburn
  0 siblings, 0 replies; 6+ messages in thread
From: Glenn Washburn @ 2022-08-15 20:28 UTC (permalink / raw)
  To: Patrick Steinhardt; +Cc: grub-devel, Daniel Kiper

On Mon, 15 Aug 2022 17:28:24 +0200
Patrick Steinhardt <ps@pks.im> wrote:

> On Thu, Aug 11, 2022 at 12:48:43PM -0500, Glenn Washburn wrote:
> > A user can now specify UUID strings with dashes, instead of having to remove
> > dashes. This is backwards-compatability preserving and also fixes a source
> > of user confusion over the inconsistency with how UUIDs are specified
> > between file system UUIDs and cryptomount UUIDs. Since cryptsetup, the
> > reference implementation for LUKS, displays and generates UUIDs with dashes
> > there has been additional confusion when using the UUID strings from
> > cryptsetup as exact input into GRUB does not find the expected cryptodisk.
> > 
> > A new function grub_uuidcasecmp is added that is general enough to be used
> > other places where UUIDs are being compared.
> > 
> > Signed-off-by: Glenn Washburn <development@efficientek.com>
> > ---
> >  grub-core/disk/cryptodisk.c |  4 ++--
> >  grub-core/disk/geli.c       |  2 +-
> >  grub-core/disk/luks.c       | 21 ++++-----------------
> >  grub-core/disk/luks2.c      | 15 ++++-----------
> >  include/grub/misc.h         | 28 ++++++++++++++++++++++++++++
> >  5 files changed, 39 insertions(+), 31 deletions(-)
> > 
> > diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
> > index f1fe0d390..00d66ab02 100644
> > --- a/grub-core/disk/cryptodisk.c
> > +++ b/grub-core/disk/cryptodisk.c
> > @@ -701,7 +701,7 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk)
> >    if (grub_memcmp (name, "cryptouuid/", sizeof ("cryptouuid/") - 1) == 0)
> >      {
> >        for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
> > -	if (grub_strcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid) == 0)
> > +	if (grub_uuidcasecmp (name + sizeof ("cryptouuid/") - 1, dev->uuid, sizeof (dev->uuid)) == 0)
> >  	  break;
> >      }
> >    else
> > @@ -928,7 +928,7 @@ grub_cryptodisk_get_by_uuid (const char *uuid)
> >  {
> >    grub_cryptodisk_t dev;
> >    for (dev = cryptodisk_list; dev != NULL; dev = dev->next)
> > -    if (grub_strcasecmp (dev->uuid, uuid) == 0)
> > +    if (grub_uuidcasecmp (dev->uuid, uuid, sizeof (dev->uuid)) == 0)
> >        return dev;
> >    return NULL;
> >  }
> > diff --git a/grub-core/disk/geli.c b/grub-core/disk/geli.c
> > index e190066f9..722910d64 100644
> > --- a/grub-core/disk/geli.c
> > +++ b/grub-core/disk/geli.c
> > @@ -305,7 +305,7 @@ geli_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
> >        return NULL;
> >      }
> >  
> > -  if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
> > +  if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, uuid, sizeof (uuid)) != 0)
> >      {
> >        grub_dprintf ("geli", "%s != %s\n", uuid, cargs->search_uuid);
> >        return NULL;
> > diff --git a/grub-core/disk/luks.c b/grub-core/disk/luks.c
> > index 7f837d52c..9e1e6a5d9 100644
> > --- a/grub-core/disk/luks.c
> > +++ b/grub-core/disk/luks.c
> > @@ -66,10 +66,7 @@ static grub_cryptodisk_t
> >  luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
> >  {
> >    grub_cryptodisk_t newdev;
> > -  const char *iptr;
> >    struct grub_luks_phdr header;
> > -  char *optr;
> > -  char uuid[sizeof (header.uuid) + 1];
> >    char ciphername[sizeof (header.cipherName) + 1];
> >    char ciphermode[sizeof (header.cipherMode) + 1];
> >    char hashspec[sizeof (header.hashSpec) + 1];
> > @@ -92,19 +89,9 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
> >        || grub_be_to_cpu16 (header.version) != 1)
> >      return NULL;
> >  
> > -  grub_memset (uuid, 0, sizeof (uuid));
> > -  optr = uuid;
> > -  for (iptr = header.uuid; iptr < &header.uuid[ARRAY_SIZE (header.uuid)];
> > -       iptr++)
> > +  if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, header.uuid, sizeof (header.uuid)) != 0)
> >      {
> > -      if (*iptr != '-')
> > -	*optr++ = *iptr;
> > -    }
> > -  *optr = 0;
> > -
> > -  if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
> > -    {
> > -      grub_dprintf ("luks", "%s != %s\n", uuid, cargs->search_uuid);
> > +      grub_dprintf ("luks", "%s != %s\n", header.uuid, cargs->search_uuid);
> >        return NULL;
> >      }
> >  
> > @@ -123,7 +110,7 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
> >    newdev->source_disk = NULL;
> >    newdev->log_sector_size = GRUB_LUKS1_LOG_SECTOR_SIZE;
> >    newdev->total_sectors = grub_disk_native_sectors (disk) - newdev->offset_sectors;
> > -  grub_memcpy (newdev->uuid, uuid, sizeof (uuid));
> > +  grub_memcpy (newdev->uuid, header.uuid, sizeof (header.uuid));
> >    newdev->modname = "luks";
> >  
> >    /* Configure the hash used for the AF splitter and HMAC.  */
> > @@ -143,7 +130,7 @@ luks_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
> >        return NULL;
> >      }
> >  
> > -  COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (uuid));
> > +  COMPILE_TIME_ASSERT (sizeof (newdev->uuid) >= sizeof (header.uuid));
> >    return newdev;
> >  }
> >  
> > diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
> > index bf741d70f..ac3ab095c 100644
> > --- a/grub-core/disk/luks2.c
> > +++ b/grub-core/disk/luks2.c
> > @@ -350,8 +350,6 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
> >  {
> >    grub_cryptodisk_t cryptodisk;
> >    grub_luks2_header_t header;
> > -  char uuid[sizeof (header.uuid) + 1];
> > -  grub_size_t i, j;
> >  
> >    if (cargs->check_boot)
> >      return NULL;
> > @@ -362,14 +360,9 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
> >        return NULL;
> >      }
> >  
> > -  for (i = 0, j = 0; i < sizeof (header.uuid); i++)
> > -    if (header.uuid[i] != '-')
> > -      uuid[j++] = header.uuid[i];
> > -  uuid[j] = '\0';
> > -
> > -  if (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, uuid) != 0)
> > +  if (cargs->search_uuid != NULL && grub_uuidcasecmp (cargs->search_uuid, header.uuid, sizeof (header.uuid)) != 0)
> >      {
> > -      grub_dprintf ("luks2", "%s != %s\n", uuid, cargs->search_uuid);
> > +      grub_dprintf ("luks2", "%s != %s\n", header.uuid, cargs->search_uuid);
> >        return NULL;
> >      }
> >  
> > @@ -377,8 +370,8 @@ luks2_scan (grub_disk_t disk, grub_cryptomount_args_t cargs)
> >    if (!cryptodisk)
> >      return NULL;
> >  
> > -  COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (uuid));
> > -  grub_memcpy (cryptodisk->uuid, uuid, sizeof (uuid));
> > +  COMPILE_TIME_ASSERT (sizeof (cryptodisk->uuid) >= sizeof (header.uuid));
> > +  grub_memcpy (cryptodisk->uuid, header.uuid, sizeof (header.uuid));
> >  
> >    cryptodisk->modname = "luks2";
> >    return cryptodisk;
> > diff --git a/include/grub/misc.h b/include/grub/misc.h
> > index 1c25c1767..2ed378188 100644
> > --- a/include/grub/misc.h
> > +++ b/include/grub/misc.h
> > @@ -244,6 +244,34 @@ grub_strncasecmp (const char *s1, const char *s2, grub_size_t n)
> >      - (int) grub_tolower ((grub_uint8_t) *s2);
> >  }
> >  
> > +/* Do a case insensitive compare of two UUID strings by ignoring all dashes */
> > +static inline int
> > +grub_uuidcasecmp (const char *uuid1, const char *uuid2, grub_size_t n)
> 
> Nit: I find it a bit unclear with how `n` is supposed to be used. You
> might expect it to denote the maximum length of either of the UUIDs, but
> it's not really given that you skip over dashes without decrementing it.
> So this rather looks like the "length of non-dash characters in either
> of the UUIDs", which is likely not all that useful to the caller.

The intent was to make grub_uuidcasecmp bounded regardless of the
contents pointed to by uuid1 or uuid2 _and_ to allow specifying the
number of significant characters to compare. This way the function
could be used to compare other uuid-like strings, like fat volume ids,
which have only 8 significant characters. I'll admit that this series
uses grub_uuidcasecmp with the size of the LUKS header uuid, which
includes the dashes. But that's only a problem if one of the strings is
not null terminated and still a problem in the alternate implementation
below. And this could be easily change to use n = 32, which can't be
done with the suggestion below. So the current implementation handles
well uuid strings that are not null terminated (eg. in the middle of a
larger string). Admittedly, that feature is not being used at the
moment.

> 
> We should either clearly document the intent of this parameter, or make
> it more useful by e.g. allowing the caller to pass both a `uuid1len` and
> `uuid2len`, which get properly decremented when skipping over dashes.

I'll add documentation.

Glenn

> 
> Patrick
> 
> > +{
> > +  if (n == 0)
> > +    return 0;
> > +
> > +  while (*uuid1 && *uuid2 && --n)
> > +    {
> > +      /* Skip forward to non-dash on both UUIDs. */
> > +      while ('-' == *uuid1)
> > +        ++uuid1;
> > +
> > +      while ('-' == *uuid2)
> > +        ++uuid2;
> > +
> > +      if (grub_tolower ((grub_uint8_t) *uuid1)
> > +	  != grub_tolower ((grub_uint8_t) *uuid2))
> > +	break;
> > +
> > +      uuid1++;
> > +      uuid2++;
> > +    }
> > +
> > +  return (int) grub_tolower ((grub_uint8_t) *uuid1)
> > +    - (int) grub_tolower ((grub_uint8_t) *uuid2);
> > +}
> > +
> >  /*
> >   * Note that these differ from the C standard's definitions of strtol,
> >   * strtoul(), and strtoull() by the addition of two const qualifiers on the end
> > -- 
> > 2.34.1
> > 


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v5 1/2] misc: Add cast in grub_strncasecmp() to drop sign when calling grub_tolower()
  2022-08-11 17:48 ` [PATCH v5 1/2] misc: Add cast in grub_strncasecmp() to drop sign when calling grub_tolower() Glenn Washburn
@ 2022-08-19 16:51   ` Daniel Kiper
  0 siblings, 0 replies; 6+ messages in thread
From: Daniel Kiper @ 2022-08-19 16:51 UTC (permalink / raw)
  To: Glenn Washburn; +Cc: grub-devel, Patrick Steinhardt

On Thu, Aug 11, 2022 at 12:48:42PM -0500, Glenn Washburn wrote:
> Note this cast was fixed in grub_strcasecmp() in commit ce41ab7aab
> (* grub-core/kern/misc.c (grub_strcmp): Use unsigned comparison as per
> common usage and preffered in several parts of code.), but this commit
> omitted fixing it in grub_strncasecmp().
>
> Signed-off-by: Glenn Washburn <development@efficientek.com>

Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>

Daniel


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-08-19 16:51 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-08-11 17:48 [PATCH v5 0/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner Glenn Washburn
2022-08-11 17:48 ` [PATCH v5 1/2] misc: Add cast in grub_strncasecmp() to drop sign when calling grub_tolower() Glenn Washburn
2022-08-19 16:51   ` Daniel Kiper
2022-08-11 17:48 ` [PATCH v5 2/2] cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner Glenn Washburn
2022-08-15 15:28   ` Patrick Steinhardt
2022-08-15 20:28     ` Glenn Washburn

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.