]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
* grub-core/fs/zfs/zfs.c (nvlist_find_value): Check that we don't go
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 27 Jan 2012 12:50:21 +0000 (13:50 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 27 Jan 2012 12:50:21 +0000 (13:50 +0100)
pastthe end.

ChangeLog
grub-core/fs/zfs/zfs.c

index 20b662316ca250c9bed0f211c6fb25db613e5a28..49a0ffb03a665525e8e3dca28e73afe5be135956 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2012-01-27  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       * grub-core/fs/zfs/zfs.c (nvlist_find_value): Check that we don't go
+       pastthe end.
+
 2012-01-27  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * util/grub-install.in: Add missing \.
index dcc1faefe7dca4b2190b0f3807ba17317653e81e..a972ad32f6fc29bf887786286fb859b6b8b6efba 100644 (file)
@@ -3039,12 +3039,12 @@ dnode_get_fullpath (const char *fullpath, struct subvolume *subvol,
  */
 
 static int
-nvlist_find_value (const char *nvlist, const char *name,
+nvlist_find_value (const char *nvlist_in, const char *name,
                   int valtype, char **val,
                   grub_size_t *size_out, grub_size_t *nelm_out)
 {
   int name_len, type, encode_size;
-  const char *nvpair, *nvp_name;
+  const char *nvpair, *nvp_name, *nvlist = nvlist_in;
 
   /* Verify if the 1st and 2nd byte in the nvlist are valid. */
   /* NOTE: independently of what endianness header announces all 
@@ -3067,6 +3067,13 @@ nvlist_find_value (const char *nvlist, const char *name,
     {
       int nelm;
 
+      if (nvlist + 4 * 4 >= nvlist_in + VDEV_PHYS_SIZE)
+       {
+         grub_dprintf ("zfs", "nvlist overflow\n");
+         grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist");
+         return 0;
+       }
+
       nvpair = nvlist + 4 * 2; /* skip the encode/decode size */
 
       name_len = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair));
@@ -3075,6 +3082,15 @@ nvlist_find_value (const char *nvlist, const char *name,
       nvp_name = nvpair;
       nvpair = nvpair + ((name_len + 3) & ~3); /* align */
 
+      if (nvpair + 8 >= nvlist_in + VDEV_PHYS_SIZE
+         || encode_size < 0
+         || nvpair + 8 + encode_size > nvlist_in + VDEV_PHYS_SIZE)
+       {
+         grub_dprintf ("zfs", "nvlist overflow\n");
+         grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist");
+         return 0;
+       }
+
       type = grub_be_to_cpu32 (grub_get_unaligned32 (nvpair));
       nvpair += 4;