]> git.proxmox.com Git - grub2.git/blobdiff - grub-core/fs/btrfs.c
btrfs: fix get_root key comparison failures due to endianness
[grub2.git] / grub-core / fs / btrfs.c
index 49f11cc3c1b337df399a384f09fee643abdd25b6..f7b6c1520371cb16c22ff9aae60f462d26223758 100644 (file)
@@ -53,7 +53,7 @@ struct grub_btrfs_device
   grub_uint64_t device_id;
   grub_uint64_t size;
   grub_uint8_t dummy[0x62 - 0x10];
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 struct grub_btrfs_superblock
 {
@@ -71,7 +71,7 @@ struct grub_btrfs_superblock
   char label[0x100];
   grub_uint8_t dummy4[0x100];
   grub_uint8_t bootstrap_mapping[0x800];
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 struct btrfs_header
 {
@@ -80,7 +80,7 @@ struct btrfs_header
   grub_uint8_t dummy[0x30];
   grub_uint32_t nitems;
   grub_uint8_t level;
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 struct grub_btrfs_device_desc
 {
@@ -122,28 +122,28 @@ struct grub_btrfs_chunk_item
   grub_uint8_t dummy2[0xc];
   grub_uint16_t nstripes;
   grub_uint16_t nsubstripes;
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 struct grub_btrfs_chunk_stripe
 {
   grub_uint64_t device_id;
   grub_uint64_t offset;
   grub_btrfs_uuid_t device_uuid;
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 struct grub_btrfs_leaf_node
 {
   struct grub_btrfs_key key;
   grub_uint32_t offset;
   grub_uint32_t size;
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 struct grub_btrfs_internal_node
 {
   struct grub_btrfs_key key;
   grub_uint64_t addr;
   grub_uint64_t dummy;
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 struct grub_btrfs_dir_item
 {
@@ -156,7 +156,7 @@ struct grub_btrfs_dir_item
 #define GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK 7
   grub_uint8_t type;
   char name[0];
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 struct grub_btrfs_leaf_descriptor
 {
@@ -183,7 +183,7 @@ struct grub_btrfs_inode
   grub_uint64_t size;
   grub_uint8_t dummy2[0x70];
   struct grub_btrfs_time mtime;
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 struct grub_btrfs_extent_data
 {
@@ -204,7 +204,7 @@ struct grub_btrfs_extent_data
       grub_uint64_t filled;
     };
   };
-} __attribute__ ((packed));
+} GRUB_PACKED;
 
 #define GRUB_BTRFS_EXTENT_INLINE 0
 #define GRUB_BTRFS_EXTENT_REGULAR 1
@@ -911,7 +911,6 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off,
 {
   grub_uint32_t total_size, cblock_size;
   grub_size_t ret = 0;
-  unsigned char buf[GRUB_BTRFS_LZO_BLOCK_SIZE];
   char *ibuf0 = ibuf;
 
   total_size = grub_le_to_cpu32 (grub_get_unaligned32 (ibuf));
@@ -955,13 +954,21 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off,
       if (off > 0 || osize < GRUB_BTRFS_LZO_BLOCK_SIZE)
        {
          grub_size_t to_copy = GRUB_BTRFS_LZO_BLOCK_SIZE - off;
+         grub_uint8_t *buf;
 
          if (to_copy > osize)
            to_copy = osize;
 
+         buf = grub_malloc (GRUB_BTRFS_LZO_BLOCK_SIZE);
+         if (!buf)
+           return -1;
+
          if (lzo1x_decompress_safe ((lzo_bytep)ibuf, cblock_size, buf, &usize,
              NULL) != LZO_E_OK)
-           return -1;
+           {
+             grub_free (buf);
+             return -1;
+           }
 
          if (to_copy > usize)
            to_copy = usize;
@@ -972,6 +979,8 @@ grub_btrfs_lzo_decompress(char *ibuf, grub_size_t isize, grub_off_t off,
          obuf += to_copy;
          ibuf += cblock_size;
          off = 0;
+
+         grub_free (buf);
          continue;
        }
 
@@ -1095,7 +1104,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
                                         - (grub_uint8_t *) data->extent),
                                        extoff, buf, csize)
                  != (grub_ssize_t) csize)
-               return -1;
+               {
+                 if (!grub_errno)
+                   grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
+                               "premature end of compressed");
+                 return -1;
+               }
            }
          else if (data->extent->compression == GRUB_BTRFS_COMPRESSION_LZO)
            {
@@ -1149,7 +1163,12 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
              grub_free (tmp);
 
              if (ret != (grub_ssize_t) csize)
-               return -1;
+               {
+                 if (!grub_errno)
+                   grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
+                               "premature end of compressed");
+                 return -1;
+               }
 
              break;
            }
@@ -1182,7 +1201,7 @@ get_root (struct grub_btrfs_data *data, struct grub_btrfs_key *key,
   struct grub_btrfs_key key_out, key_in;
   struct grub_btrfs_root_item ri;
 
-  key_in.object_id = GRUB_BTRFS_ROOT_VOL_OBJECTID;
+  key_in.object_id = grub_cpu_to_le64_compile_time (GRUB_BTRFS_ROOT_VOL_OBJECTID);
   key_in.offset = 0;
   key_in.type = GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM;
   err = lower_bound (data, &key_in, &key_out,