]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - lib/decompress_unlz4.c
initrd: fix lz4 decompress with initrd
[mirror_ubuntu-artful-kernel.git] / lib / decompress_unlz4.c
index 7d1e83caf8ad8512c3a0d39e4f5e5b5c39de619f..3ad7f3954dfd23b27a87380e75d384f3056d609a 100644 (file)
@@ -83,13 +83,20 @@ STATIC inline int INIT unlz4(u8 *input, int in_len,
        if (posp)
                *posp = 0;
 
-       if (fill)
-               fill(inp, 4);
+       if (fill) {
+               size = fill(inp, 4);
+               if (size < 4) {
+                       error("data corrupted");
+                       goto exit_2;
+               }
+       }
 
        chunksize = get_unaligned_le32(inp);
        if (chunksize == ARCHIVE_MAGICNUMBER) {
-               inp += 4;
-               size -= 4;
+               if (!fill) {
+                       inp += 4;
+                       size -= 4;
+               }
        } else {
                error("invalid header");
                goto exit_2;
@@ -100,29 +107,44 @@ STATIC inline int INIT unlz4(u8 *input, int in_len,
 
        for (;;) {
 
-               if (fill)
-                       fill(inp, 4);
+               if (fill) {
+                       size = fill(inp, 4);
+                       if (size == 0)
+                               break;
+                       if (size < 4) {
+                               error("data corrupted");
+                               goto exit_2;
+                       }
+               }
 
                chunksize = get_unaligned_le32(inp);
                if (chunksize == ARCHIVE_MAGICNUMBER) {
-                       inp += 4;
-                       size -= 4;
+                       if (!fill) {
+                               inp += 4;
+                               size -= 4;
+                       }
                        if (posp)
                                *posp += 4;
                        continue;
                }
-               inp += 4;
-               size -= 4;
+
 
                if (posp)
                        *posp += 4;
 
-               if (fill) {
+               if (!fill) {
+                       inp += 4;
+                       size -= 4;
+               } else {
                        if (chunksize > lz4_compressbound(uncomp_chunksize)) {
                                error("chunk length is longer than allocated");
                                goto exit_2;
                        }
-                       fill(inp, chunksize);
+                       size = fill(inp, chunksize);
+                       if (size < chunksize) {
+                               error("data corrupted");
+                               goto exit_2;
+                       }
                }
 #ifdef PREBOOT
                if (out_len >= uncomp_chunksize) {
@@ -149,18 +171,17 @@ STATIC inline int INIT unlz4(u8 *input, int in_len,
                if (posp)
                        *posp += chunksize;
 
-               size -= chunksize;
+               if (!fill) {
+                       size -= chunksize;
 
-               if (size == 0)
-                       break;
-               else if (size < 0) {
-                       error("data corrupted");
-                       goto exit_2;
+                       if (size == 0)
+                               break;
+                       else if (size < 0) {
+                               error("data corrupted");
+                               goto exit_2;
+                       }
+                       inp += chunksize;
                }
-
-               inp += chunksize;
-               if (fill)
-                       inp = inp_start;
        }
 
        ret = 0;