grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Implement checksum verification for gunzip


From: Vladimir 'phcoder' Serbinenko
Subject: Re: [PATCH] Implement checksum verification for gunzip
Date: Wed, 30 Aug 2017 14:08:15 +0000

Committed, thanks

Le Sun, May 1, 2016 à 2:33 PM, Stefan Fritsch <address@hidden> a écrit :
This implements the crc32 check for the gzip format. Support for zlib's
adler checksum is not included, yet.

diff --git a/contrib/grub2/grub-core/io/gzio.c b/contrib/grub2/grub-core/io/gzio.c
index 0f2ea6b..432f0aa 100644
--- a/contrib/grub2/grub-core/io/gzio.c
+++ b/contrib/grub2/grub-core/io/gzio.c
@@ -43,6 +43,7 @@
 #include <grub/dl.h>
 #include <grub/deflate.h>
 #include <grub/i18n.h>
+#include <grub/crypto.h>

 GRUB_MOD_LICENSE ("GPLv3+");

@@ -94,6 +95,14 @@ struct grub_gzio
   struct huft *tl;
   /* The distance code table.  */
   struct huft *td;
+  /* The checksum algorithm */
+  const gcry_md_spec_t *hdesc;
+  /* The wanted checksum */
+  grub_uint32_t orig_checksum;
+  /* The uncompressed length */
+  grub_size_t orig_len;
+  /* Context for checksum calculation */
+  grub_uint8_t *hcontext;
   /* The lookup bits for the literal/length code table. */
   int bl;
   /* The lookup bits for the distance code table.  */
@@ -180,7 +189,7 @@ test_gzip_header (grub_file_t file)
     grub_uint8_t os_type;
   } hdr;
   grub_uint16_t extra_len;
-  grub_uint32_t orig_len;
+  grub_uint32_t crc32;
   grub_gzio_t gzio = file->data;

   if (grub_file_tell (gzio->file) != 0)
@@ -215,12 +224,15 @@ test_gzip_header (grub_file_t file)

   /* FIXME: don't do this on not easily seekable files.  */
   {
-    grub_file_seek (gzio->file, grub_file_size (gzio->file) - 4);
-    if (grub_file_read (gzio->file, &orig_len, 4) != 4)
+    grub_file_seek (gzio->file, grub_file_size (gzio->file) - 8);
+    if (grub_file_read (gzio->file, &crc32, 4) != 4)
+      return 0;
+    gzio->orig_checksum = grub_le_to_cpu32 (crc32);
+    if (grub_file_read (gzio->file, &gzio->orig_len, 4) != 4)
       return 0;
     /* FIXME: this does not handle files whose original size is over 4GB.
        But how can we know the real original size?  */
-    file->size = grub_le_to_cpu32 (orig_len);
+    file->size = grub_le_to_cpu32 (gzio->orig_len);
   }

   initialize_tables (gzio);
@@ -1095,7 +1107,23 @@ inflate_window (grub_gzio_t gzio)

   gzio->saved_offset += gzio->wp;

-  /* XXX do CRC calculation here! */
+  if (gzio->hcontext)
+    {
+      gzio->hdesc->write (gzio->hcontext, gzio->slide, gzio->wp);
+
+      if (gzio->saved_offset == gzio->orig_len)
+       {
+         grub_uint32_t csum;
+
+         gzio->hdesc->final (gzio->hcontext);
+         csum = *(grub_uint32_t *)gzio->hdesc->read (gzio->hcontext);
+         csum = grub_be_to_cpu32 (csum);
+         if (csum != gzio->orig_checksum)
+           grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
+                       "checksum mismatch %08x/%08x",
+                       gzio->orig_checksum, csum);
+       }
+    }
 }


@@ -1118,6 +1146,9 @@ initialize_tables (grub_gzio_t gzio)
   huft_free (gzio->td);
   gzio->tl = NULL;
   gzio->td = NULL;
+
+  if (gzio->hcontext)
+    gzio->hdesc->init(gzio->hcontext);
 }


@@ -1143,6 +1174,9 @@ grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused)))

   gzio->file = io;

+  gzio->hdesc = GRUB_MD_CRC32;
+  gzio->hcontext = grub_malloc(gzio->hdesc->contextsize);
+
   file->device = io->device;
   file->data = "">    file->fs = &grub_gzio_fs;
@@ -1151,6 +1185,7 @@ grub_gzio_open (grub_file_t io, const char *name __attribute__ ((unused)))
   if (! test_gzip_header (file))
     {
       grub_errno = GRUB_ERR_NONE;
+      grub_free (gzio->hcontext);
       grub_free (gzio);
       grub_free (file);
       grub_file_seek (io, 0);
@@ -1287,6 +1322,7 @@ grub_gzio_close (grub_file_t file)
   grub_file_close (gzio->file);
   huft_free (gzio->tl);
   huft_free (gzio->td);
+  grub_free (gzio->hcontext);
   grub_free (gzio);

   /* No need to close the same device twice.  */

_______________________________________________
Grub-devel mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/grub-devel

reply via email to

[Prev in Thread] Current Thread [Next in Thread]