Bug #170
closedcbfstool fails to export payloads (unknown compression error)
0%
Description
(from b/111576981)
Problem encountered:
$ cbfstool tianocore.cbfs extract -m x86 -n payload -f /tmp/payload -v -v
INFO: Opening image as a flat file because it doesn't contain any FMAP
DEBUG: cbfs_get_entry: found payload
Found file payload at 0x0, type simple elf, size 650878
E: Unknown compression algorithm 31!
E: Unknown decompression algorithm: 31E: Failed to decompress payload.
Expected behaviour:
$ cbfstool tianocore.cbfs extract -m x86 -n payload -f /tmp/payload -v -v
INFO: Opening image as a flat file because it doesn't contain any FMAP
DEBUG: cbfs_get_entry: found payload
Found file payload at 0x0, type payload, size 650878
INFO: Writing 5 sections.
INFO: Created 4268032 output buffer for ELF file.
INFO: Successfully dumped the file to: /tmp/payload
Why this occurs:
In cbfs-mkpayload.c, when creating PAYLOAD_SEGMENT_ENTRY segments, the only field that is written to is |load_addr|. The |compression| field is left unset, which is presumably taking on some random or deterministic value that happens to be in memory at that location.
The cbfs extract command calls into cbfs_payload_decompress, which ensures each segment has a valid compression algorithm. When it encounters a value other than 0/1/2, it throws an error and fails.
Solution:
Option A: Write CBFS_COMPRESS_NONE value to the |compression| field for PAYLOAD_SEGMENT_ENTRY (also _BSS and _PARAMS).
Option B: Ignore the |compression| field in cbfstool extract command for these payload segment types.
Updated by Joel Kitching over 6 years ago
From responses at https://review.coreboot.org/#/c/27520/ it seems the general opinion is that both sides of the problem should be solved.
Just to give a clearer illustration of what is going on, here is what the top of a tianocore.cbfs file looks like:
$ xxd tianocore.cbfs | head
00000000: 4c41 5243 4849 5645 0009 ee7e 0000 0020 LARCHIVE...~...
00000010: 0000 0000 0000 0028 7061 796c 6f61 6400 .......(payload.
00000020: 0000 0000 0000 0000 434f 4445 0000 0001 ........CODE....
00000030: 0000 0038 0000 0000 0080 0000 0009 ee46 ...8...........F
00000040: 0041 0000 454e 5452 0000 001f 0000 0023 .A..ENTR.......# Note the 0x1f = 31
00000050: 0000 0000 0080 0810 0000 002f 0000 0033 .........../...3
And here's what it looks like after adding some memset(0) calls on the segment header array:
$ xxd tianocore.cbfs | head
00000000: 4c41 5243 4849 5645 0009 ee7e 0000 0020 LARCHIVE...~...
00000010: 0000 0000 0000 0028 7061 796c 6f61 6400 .......(payload.
00000020: 0000 0000 0000 0000 434f 4445 0000 0001 ........CODE....
00000030: 0000 0038 0000 0000 0080 0000 0009 ee46 ...8...........F
00000040: 0041 0000 454e 5452 0000 0000 0000 0000 .A..ENTR........
00000050: 0000 0000 0080 0810 0000 0000 0000 0000 ................