Skip to content

Commit

Permalink
lib: fix the use of LZO to decompress initramfs images
Browse files Browse the repository at this point in the history
This patch fixes 2 issues with the LZO decompressor:

- It doesn't handle the case where a block isn't compressed at all.  In
  this case, calling lzo1x_decompress_safe will fail, so we need to just
  use memcpy() instead (the upstream LZO code does something similar)

- Since commit 5429136 ("initramfs: add
  missing decompressor error check") , the decompressor return code is
  checked in the init/initramfs.c The LZO decompressor didn't return the
  expected value, causing the initramfs code to falsely believe a
  decompression error occured

Signed-off-by: Albin Tonnerre <albin.tonnerre@free-electrons.com>
Tested-by: bert schulze <spambemyguest@googlemail.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Albin Tonnerre authored and torvalds committed Apr 24, 2010
1 parent 23be746 commit ccdb400
Showing 1 changed file with 15 additions and 7 deletions.
22 changes: 15 additions & 7 deletions lib/decompress_unlzo.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
u32 src_len, dst_len;
size_t tmp;
u8 *in_buf, *in_buf_save, *out_buf;
int obytes_processed = 0;
int ret = -1;

set_error_fn(error_fn);

Expand Down Expand Up @@ -174,15 +174,22 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,

/* decompress */
tmp = dst_len;
r = lzo1x_decompress_safe((u8 *) in_buf, src_len,

/* When the input data is not compressed at all,
* lzo1x_decompress_safe will fail, so call memcpy()
* instead */
if (unlikely(dst_len == src_len))
memcpy(out_buf, in_buf, src_len);
else {
r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
out_buf, &tmp);

if (r != LZO_E_OK || dst_len != tmp) {
error("Compressed data violation");
goto exit_2;
if (r != LZO_E_OK || dst_len != tmp) {
error("Compressed data violation");
goto exit_2;
}
}

obytes_processed += dst_len;
if (flush)
flush(out_buf, dst_len);
if (output)
Expand All @@ -196,14 +203,15 @@ STATIC inline int INIT unlzo(u8 *input, int in_len,
in_buf += src_len;
}

ret = 0;
exit_2:
if (!input)
free(in_buf);
exit_1:
if (!output)
free(out_buf);
exit:
return obytes_processed;
return ret;
}

#define decompress unlzo

0 comments on commit ccdb400

Please sign in to comment.