Skip to content

Commit 1a263b7

Browse files
xnoxksacilotto
authored andcommitted
UBUNTU: SAUCE: lib/decompress_unlz4.c: correctly handle zero-padding around initrds.
lz4 compatible decompressor is simple. The format is underspecified and relies on EOF notification to determine when to stop. Initramfs buffer format[1] explicitely states that it can have arbitrary number of zero padding. Thus when operating without a fill function, be extra careful to ensure that sizes less than 4, or apperantly empty chunksizes are treated as EOF. To test this I have created two cpio initrds, first a normal one, main.cpio. And second one with just a single /test-file with content "second" second.cpio. Then i compressed both of them with gzip, and with lz4 -l. Then I created a padding of 4 bytes (dd if=/dev/zero of=pad4 bs=1 count=4). To create four testcase initrds: 1) main.cpio.gzip + extra.cpio.gzip = pad0.gzip 2) main.cpio.lz4 + extra.cpio.lz4 = pad0.lz4 3) main.cpio.gzip + pad4 + extra.cpio.gzip = pad4.gzip 4) main.cpio.lz4 + pad4 + extra.cpio.lz4 = pad4.lz4 The pad4 test-cases replicate the initrd load by grub, as it pads and aligns every initrd it loads. All of the above boot, however /test-file was not accessible in the initrd for the testcase #4, as decoding in lz4 decompressor failed. Also an error message printed which usually is harmless. Whith a patched kernel, all of the above testcases now pass, and /test-file is accessible. This fixes lz4 initrd decompress warning on every boot with grub. And more importantly this fixes inability to load multiple lz4 compressed initrds with grub. I guess I should convert above decompressor streams with/without padding into kunit tests, across all decompressor algorithms. [1] https://www.kernel.org/doc/html/latest/driver-api/early-userspace/buffer-format.html BugLink: https://bugs.launchpad.net/bugs/1835660 Signed-off-by: Dimitri John Ledkov <xnox@ubuntu.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> Acked-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com> Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
1 parent 1a10993 commit 1a263b7

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

lib/decompress_unlz4.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ STATIC inline int INIT unlz4(u8 *input, long in_len,
112112
error("data corrupted");
113113
goto exit_2;
114114
}
115+
} else if (size < 4) {
116+
/* empty or end-of-file */
117+
goto exit_3;
115118
}
116119

117120
chunksize = get_unaligned_le32(inp);
@@ -125,6 +128,10 @@ STATIC inline int INIT unlz4(u8 *input, long in_len,
125128
continue;
126129
}
127130

131+
if (!fill && chunksize == 0) {
132+
/* empty or end-of-file */
133+
goto exit_3;
134+
}
128135

129136
if (posp)
130137
*posp += 4;
@@ -184,6 +191,7 @@ STATIC inline int INIT unlz4(u8 *input, long in_len,
184191
}
185192
}
186193

194+
exit_3:
187195
ret = 0;
188196
exit_2:
189197
if (!input)

0 commit comments

Comments
 (0)