Commit ccdb40048b2972f10bdc944913c0e0ee26b5d1f2

Authored by Albin Tonnerre
Committed by Linus Torvalds
1 parent 23be7468e8

lib: fix the use of LZO to decompress initramfs images

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 54291362d2a5738e1b0495df2abcb9e6b0563a3f ("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>

Showing 1 changed file with 15 additions and 7 deletions Side-by-side Diff

lib/decompress_unlzo.c
... ... @@ -97,7 +97,7 @@
97 97 u32 src_len, dst_len;
98 98 size_t tmp;
99 99 u8 *in_buf, *in_buf_save, *out_buf;
100   - int obytes_processed = 0;
  100 + int ret = -1;
101 101  
102 102 set_error_fn(error_fn);
103 103  
104 104  
105 105  
... ... @@ -174,15 +174,22 @@
174 174  
175 175 /* decompress */
176 176 tmp = dst_len;
177   - r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
  177 +
  178 + /* When the input data is not compressed at all,
  179 + * lzo1x_decompress_safe will fail, so call memcpy()
  180 + * instead */
  181 + if (unlikely(dst_len == src_len))
  182 + memcpy(out_buf, in_buf, src_len);
  183 + else {
  184 + r = lzo1x_decompress_safe((u8 *) in_buf, src_len,
178 185 out_buf, &tmp);
179 186  
180   - if (r != LZO_E_OK || dst_len != tmp) {
181   - error("Compressed data violation");
182   - goto exit_2;
  187 + if (r != LZO_E_OK || dst_len != tmp) {
  188 + error("Compressed data violation");
  189 + goto exit_2;
  190 + }
183 191 }
184 192  
185   - obytes_processed += dst_len;
186 193 if (flush)
187 194 flush(out_buf, dst_len);
188 195 if (output)
... ... @@ -196,6 +203,7 @@
196 203 in_buf += src_len;
197 204 }
198 205  
  206 + ret = 0;
199 207 exit_2:
200 208 if (!input)
201 209 free(in_buf);
... ... @@ -203,7 +211,7 @@
203 211 if (!output)
204 212 free(out_buf);
205 213 exit:
206   - return obytes_processed;
  214 + return ret;
207 215 }
208 216  
209 217 #define decompress unlzo