busybox 1.30.1 crashes bzip2 test case with glibc 2.29, always
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
BusyBox |
Fix Released
|
Medium
|
|||
Ubuntu on IBM z Systems |
Invalid
|
High
|
bugproxy | ||
busybox (Ubuntu) |
Fix Released
|
Undecided
|
Unassigned | ||
glibc (Ubuntu) |
Invalid
|
Undecided
|
Unassigned |
Bug Description
Steps to reproduce:
1) Get a system with glibc 2.29
2) Get busybox 1.30.1 installed (e.g. eoan, or download busybox package from https:/
3) Get busybox 1.30.1 source code, e.g. $ pull-lp-source busybox
Or like download the orig tarball from https:/
4) Run the bunzip2 testsuite:
cd testsuite/
ECHO=/bin/echo ./bunzip2.tests
Observe that with glibc 2.29 the:
PASS: bunzip2: bz2_issue_11.bz2 corrupted example
is XFAIL or FAIL, on s390x, whereas it passes on all other arches.
If one uses glibc 2.28 (ie. use Cosmic, and install busybox & use matching test suite from eoan using links above) one can observe that the testcase always passes.
We suspect this might be a glibc 2.29 s390x-specific setjmp regression. Probably due to setjmp usage in ./archival/
The tests were done on a z13 machine.
Changed in ubuntu-z-systems: | |
importance: | Undecided → High |
assignee: | nobody → bugproxy (bugproxy) |
tags: | added: reverse-proxy-bugzilla s390x |
tags: | added: architecture-s39064 bugnameltc-177501 severity-high targetmilestone-inin1910 |
tags: | added: id-5cc732a8910db44841cff9f0 |
Changed in ubuntu-z-systems: | |
status: | New → Invalid |
Changed in busybox: | |
importance: | Unknown → Medium |
status: | Unknown → Confirmed |
Changed in busybox (Ubuntu): | |
status: | Triaged → Fix Committed |
Changed in busybox: | |
status: | Confirmed → Fix Released |
------- Comment From <email address hidden> 2019-05-13 07:27 EDT-------
Hi xnox,
this issue has nothing todo with an issue in s390x specific setjmp/longjmp implementation!
Setjmp/longjmp is just used for error handling inside bunzip2 implementation in busybox!
But due to an issue in busybox implementation, longjmp is called on s390x but not on e.g. x86.
Please report this bug to busybox with the detailed information below!
According to bunzip2.tests:
bunzip2: bunzip error -5 => PASS
bunzip2: bunzip error -3 => XFAIL
As side note:
Error -3 also occures on s390x Ubuntu 18.04.2 LTS!
According to archival/ libarchive/ decompress_ bunzip2. c: UNEXPECTED_ INPUT_EOF (dbg("%d", __LINE__), -3)
62#define RETVAL_
64#define RETVAL_DATA_ERROR (dbg("%d", __LINE__), -5)
RETVAL_ UNEXPECTED_ INPUT_EOF is used only in get_bits(): *bd->jmpbuf, RETVAL_ UNEXPECTED_ INPUT_EOF) ; 1.30.1/ testsuite$ gdb ../busybox_ unstripped bunzip2. c:130 bz2_stream( ). &jmpbuf, &bd, xstate->src_fd, outbuf + 2, len); msg("bunzip error %d", i);
128 bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE);
129 if (bd->inbufCount <= 0)
130 longjmp(
If you start gdb and set a breakpoint there ...:
busybox-
(gdb) b decompress_
(gdb) run bunzip2 <bz2_issue_11.bz2 2>&1 >/dev/null
... it will be hit, bd->inbufCount will be zero and the longjmp jumps back to setjmp in unpack_
i will be -3 and "bunzip error -3" will be reported.:
788 i = setjmp(jmpbuf);
789 if (i == 0)
790 i = start_bunzip(
791
792 if (i == 0) {
793 while (1) { /* "Produce some output bytes" loop */
794 i = read_bunzip(bd, outbuf, IOBUF_SIZE);
795 if (i < 0) /* error? */
796 break;
...
808 if (i != RETVAL_LAST_BLOCK
809 /* Observed case when i == RETVAL_OK:
810 * "bzcat z.bz2", where "z.bz2" is a bzipped zero-length file
811 * (to be exact, z.bz2 is exactly these 14 bytes:
812 * 42 5a 68 39 17 72 45 38 50 90 00 00 00 00).
813 */
814 && i != RETVAL_OK
815 ) {
816 bb_error_
817 break;
818 }
The difference between reporting -5 or -3 depends on uninitialized values on the stack while calling read_bunzip( )->get_ next_block( ). block(bunzip_ data *bd)
There you have the array mtfSymbol on stack:
156/* Unpacks the next block and sets up for the inverse Burrows-Wheeler step. */
157static int get_next_
158{
159 int groupCount, selector,
160 i, j, symCount, symTotal, nSelectors, byteCount[256];
161 uint8_t uc, symToByte[256], mtfSymbol[256], *selectors;
...
The groupCount is read and values in mtfSymbol are initialized:
...
219 /* How many different Huffman coding groups does this block use? */
220 groupCount = get_bits(bd, 3);
221 if (groupCount < 2 || groupCount > MAX_GROUPS)
222 return RETVAL_DATA_ERROR;
...
228 for (i = ...