]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Decrease stack usage in signature verification.
authorVladimir Serbinenko <phcoder@gmail.com>
Sat, 16 Nov 2013 15:34:51 +0000 (16:34 +0100)
committerVladimir Serbinenko <phcoder@gmail.com>
Sat, 16 Nov 2013 15:34:51 +0000 (16:34 +0100)
We have only 92K of stack and using over 4K per frame is wasteful

* grub-core/commands/verify.c (grub_load_public_key): Allocate on heap
rather than stack.
(grub_verify_signature_real): Likewise.

ChangeLog
grub-core/commands/verify.c

index 0bbc2ebc36d1624d0e08b5ecb1f19f4318eacf34..acf26a955f0ef87ce68d078bc3ef09fb147f8ad1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2013-11-16  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Decrease stack usage in signature verification.
+
+       We have only 92K of stack and using over 4K per frame is wasteful
+
+       * grub-core/commands/verify.c (grub_load_public_key): Allocate on heap
+       rather than stack.
+       (grub_verify_signature_real): Likewise.
+
 2013-11-16  Vladimir Serbinenko  <phcoder@gmail.com>
 
        Decrease stack usage in mdraid 0.9x.
index 04960c5d6082a958adb9654535267ec8dc229870..3e61c225701670a5b6747ea11ce7e0b49ae5c4b5 100644 (file)
@@ -198,17 +198,16 @@ free_pk (struct grub_public_key *pk)
   grub_free (pk);
 }
 
+#define READBUF_SIZE 4096
+
 struct grub_public_key *
 grub_load_public_key (grub_file_t f)
 {
   grub_err_t err;
   struct grub_public_key *ret;
   struct grub_public_subkey **last = 0;
-  void *fingerprint_context;
-
-  fingerprint_context = grub_zalloc (GRUB_MD_SHA1->contextsize);
-  if (!fingerprint_context)
-    return NULL;
+  void *fingerprint_context = NULL;
+  grub_uint8_t *buffer = NULL;
 
   ret = grub_zalloc (sizeof (*ret));
   if (!ret)
@@ -217,6 +216,12 @@ grub_load_public_key (grub_file_t f)
       return NULL;
     }
 
+  buffer = grub_zalloc (READBUF_SIZE);
+  fingerprint_context = grub_zalloc (GRUB_MD_SHA1->contextsize);
+
+  if (!buffer || !fingerprint_context)
+    goto fail;
+
   last = &ret->subkeys;
 
   while (1)
@@ -304,7 +309,6 @@ grub_load_public_key (grub_file_t f)
        {
          grub_uint16_t l;
          grub_size_t lb;
-         grub_uint8_t buffer[4096];
          if (grub_file_read (f, &l, sizeof (l)) != sizeof (l))
            {
              grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
@@ -312,7 +316,7 @@ grub_load_public_key (grub_file_t f)
            }
          
          lb = (grub_be_to_cpu16 (l) + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT;
-         if (lb > sizeof (buffer) - sizeof (grub_uint16_t))
+         if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
            {
              grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
              goto fail;
@@ -348,6 +352,7 @@ grub_load_public_key (grub_file_t f)
  fail:
   free_pk (ret);
   grub_free (fingerprint_context);
+  grub_free (buffer);
   return NULL;
 }
 
@@ -486,10 +491,12 @@ grub_verify_signature_real (char *buf, grub_size_t size,
     gcry_mpi_t hmpi;
     grub_uint64_t keyid = 0;
     struct grub_public_subkey *sk;
+    grub_uint8_t *readbuf = NULL;
 
     context = grub_zalloc (hash->contextsize);
-    if (!context)
-      return grub_errno;
+    readbuf = grub_zalloc (READBUF_SIZE);
+    if (!context || !readbuf)
+      goto fail;
 
     hash->init (context);
     if (buf)
@@ -497,8 +504,7 @@ grub_verify_signature_real (char *buf, grub_size_t size,
     else 
       while (1)
        {
-         grub_uint8_t readbuf[4096];
-         r = grub_file_read (f, readbuf, sizeof (readbuf));
+         r = grub_file_read (f, readbuf, READBUF_SIZE);
          if (r < 0)
            goto fail;
          if (r == 0)
@@ -510,8 +516,8 @@ grub_verify_signature_real (char *buf, grub_size_t size,
     hash->write (context, &v4, sizeof (v4));
     while (rem)
       {
-       grub_uint8_t readbuf[4096];
-       r = grub_file_read (sig, readbuf, rem < (grub_ssize_t) sizeof (readbuf) ? rem : (grub_ssize_t) sizeof (readbuf));
+       r = grub_file_read (sig, readbuf,
+                           rem < READBUF_SIZE ? rem : READBUF_SIZE);
        if (r < 0)
          goto fail;
        if (r == 0)
@@ -527,11 +533,10 @@ grub_verify_signature_real (char *buf, grub_size_t size,
     if (r != sizeof (unhashed_sub))
       goto fail;
     {
-      grub_uint8_t readbuf[4096];
       grub_uint8_t *ptr;
       grub_uint32_t l;
       rem = grub_be_to_cpu16 (unhashed_sub);
-      if (rem > (int) sizeof (readbuf))
+      if (rem > READBUF_SIZE)
        goto fail;
       r = grub_file_read (sig, readbuf, rem);
       if (r != rem)
@@ -576,24 +581,23 @@ grub_verify_signature_real (char *buf, grub_size_t size,
       {
        grub_uint16_t l;
        grub_size_t lb;
-       grub_uint8_t buffer[4096];
        grub_dprintf ("crypt", "alive\n");
        if (grub_file_read (sig, &l, sizeof (l)) != sizeof (l))
          goto fail;
        grub_dprintf ("crypt", "alive\n");
        lb = (grub_be_to_cpu16 (l) + 7) / 8;
        grub_dprintf ("crypt", "l = 0x%04x\n", grub_be_to_cpu16 (l));
-       if (lb > sizeof (buffer) - sizeof (grub_uint16_t))
+       if (lb > READBUF_SIZE - sizeof (grub_uint16_t))
          goto fail;
        grub_dprintf ("crypt", "alive\n");
-       if (grub_file_read (sig, buffer + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
+       if (grub_file_read (sig, readbuf + sizeof (grub_uint16_t), lb) != (grub_ssize_t) lb)
          goto fail;
        grub_dprintf ("crypt", "alive\n");
-       grub_memcpy (buffer, &l, sizeof (l));
+       grub_memcpy (readbuf, &l, sizeof (l));
        grub_dprintf ("crypt", "alive\n");
 
        if (gcry_mpi_scan (&mpis[i], GCRYMPI_FMT_PGP,
-                          buffer, lb + sizeof (grub_uint16_t), 0))
+                          readbuf, lb + sizeof (grub_uint16_t), 0))
          goto fail;
        grub_dprintf ("crypt", "alive\n");
       }
@@ -631,6 +635,7 @@ grub_verify_signature_real (char *buf, grub_size_t size,
 
   fail:
     grub_free (context);
+    grub_free (readbuf);
     if (!grub_errno)
       return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("bad signature"));
     return grub_errno;