LUKS: refactor multiple return paths
authorTJ <grub-devel@iam.tj>
Wed, 21 Mar 2018 14:07:22 +0000 (14:07 +0000)
committerTJ <grub-devel@iam.tj>
Wed, 21 Mar 2018 14:07:22 +0000 (14:07 +0000)
Convert multiple return statements to goto with a single return so there
is only one place where memory needs to be free-d in error conditions.

grub-core/disk/luks.c

index 86c50c6..a7c5b39 100644 (file)
@@ -318,18 +318,23 @@ 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;
+  char *err_msg = NULL;
   grub_size_t max_stripes = 1;
   char *tmp;
 
   err = grub_disk_read (source, 0, 0, sizeof (header), &header);
   if (err)
-    return err;
+    goto fail;
 
   grub_puts_ (N_("Attempting to decrypt master key..."));
   keysize = grub_be_to_cpu32 (header.keyBytes);
   if (keysize > GRUB_CRYPTODISK_MAX_KEYLEN)
-    return grub_error (GRUB_ERR_BAD_FS, "key is too long");
+    {
+      err = GRUB_ERR_BAD_FS;
+      err_msg = "key is too long";
+      goto fail;
+    }
 
   for (i = 0; i < ARRAY_SIZE (header.keyblock); i++)
     if (grub_be_to_cpu32 (header.keyblock[i].active) == LUKS_KEY_ENABLED
@@ -338,7 +343,10 @@ luks_recover_key (grub_disk_t source,
 
   split_key = grub_malloc (keysize * max_stripes);
   if (!split_key)
-    return grub_errno;
+    {
+      err = grub_errno;
+         goto fail;
+    }
 
   /* Get the passphrase from the user.  */
   tmp = NULL;
@@ -350,8 +358,9 @@ luks_recover_key (grub_disk_t source,
   grub_free (tmp);
   if (!grub_password_get (passphrase, MAX_PASSPHRASE))
     {
-      grub_free (split_key);
-      return grub_error (GRUB_ERR_BAD_ARGUMENT, "Passphrase not supplied");
+      err = GRUB_ERR_BAD_ARGUMENT;
+      err_msg = "Passphrase not supplied";
+      goto fail;
     }
 
   /* Try to recover master key from each active keyslot.  */
@@ -378,8 +387,8 @@ luks_recover_key (grub_disk_t source,
 
       if (gcry_err)
        {
-         grub_free (split_key);
-         return grub_crypto_gcry_error (gcry_err);
+         err =  grub_crypto_gcry_error (gcry_err);
+         goto fail;
        }
 
       grub_dprintf ("luks", "PBKDF2 done\n");
@@ -387,8 +396,8 @@ luks_recover_key (grub_disk_t source,
       gcry_err = grub_cryptodisk_setkey (dev, digest, keysize); 
       if (gcry_err)
        {
-         grub_free (split_key);
-         return grub_crypto_gcry_error (gcry_err);
+         err = grub_crypto_gcry_error (gcry_err);
+         goto fail;
        }
 
       length = (keysize * grub_be_to_cpu32 (header.keyblock[i].stripes));
@@ -399,16 +408,13 @@ luks_recover_key (grub_disk_t source,
                                              [i].keyMaterialOffset), 0,
                            length, split_key);
       if (err)
-       {
-         grub_free (split_key);
-         return err;
-       }
+          goto fail;
 
       gcry_err = grub_cryptodisk_decrypt (dev, split_key, length, 0);
       if (gcry_err)
        {
-         grub_free (split_key);
-         return grub_crypto_gcry_error (gcry_err);
+         err = grub_crypto_gcry_error (gcry_err);
+         goto fail;
        }
 
       /* Merge the decrypted key material to get the candidate master key.  */
@@ -416,8 +422,8 @@ luks_recover_key (grub_disk_t source,
                           grub_be_to_cpu32 (header.keyblock[i].stripes));
       if (gcry_err)
        {
-         grub_free (split_key);
-         return grub_crypto_gcry_error (gcry_err);
+         err = grub_crypto_gcry_error (gcry_err);
+         goto fail;
        }
 
       grub_dprintf ("luks", "candidate key recovered\n");
@@ -433,8 +439,8 @@ luks_recover_key (grub_disk_t source,
                                     sizeof (candidate_digest));
       if (gcry_err)
        {
-         grub_free (split_key);
-         return grub_crypto_gcry_error (gcry_err);
+         err = grub_crypto_gcry_error (gcry_err);
+         goto fail;
        }
 
       /* Compare the calculated PBKDF2 to the digest stored
@@ -454,17 +460,19 @@ luks_recover_key (grub_disk_t source,
       gcry_err = grub_cryptodisk_setkey (dev, candidate_key, keysize); 
       if (gcry_err)
        {
-         grub_free (split_key);
-         return grub_crypto_gcry_error (gcry_err);
+         err = grub_crypto_gcry_error (gcry_err);
+         goto fail;
        }
 
-      grub_free (split_key);
-
-      return GRUB_ERR_NONE;
+      err = GRUB_ERR_NONE;
     }
 
+fail:
   grub_free (split_key);
-  return GRUB_ACCESS_DENIED;
+  if(err && err_msg)
+         grub_error (err, errmsg);
+
+  return err;
 }
 
 struct grub_cryptodisk_dev luks_crypto = {