libbacktrace: don't skip initial aligned byte in uncompressed block
authorIan Lance Taylor <iant@golang.org>
Tue, 5 Apr 2022 23:04:09 +0000 (16:04 -0700)
committerIan Lance Taylor <iant@golang.org>
Tue, 5 Apr 2022 23:09:34 +0000 (16:09 -0700)
Patch from Rui Ueyama, who says:

libbacktrace occasionally fails to decompress compressed debug info
even though the sections contain valid zlib streams. The cause of the
issue is an off-by-one error.

If a zlib data block is a plain data (uncompressed data), the next two
bytes contain the size of the block. These two bytes value is byte-
aligned, so if we read-ahead more than 8 bits, we need to unread it.

So, the correct condition to determine whether or not we need to
unread a byte is bits >= 8 and not bits > 8. Due to this error,
if the last read bits happened to end at a byte boundary, the next
byte would be skipped. That caused the decompression failure.

This bug was originally reported against the mold linker.
rui314/mold#402

* elf.c (elf_zlib_inflate): Don't skip initial aligned byte in
uncompressed block.

libbacktrace/elf.c

index 5c7c21a..8b82dd4 100644 (file)
@@ -1796,7 +1796,7 @@ elf_zlib_inflate (const unsigned char *pin, size_t sin, uint16_t *zdebug_table,
              /* An uncompressed block.  */
 
              /* If we've read ahead more than a byte, back up.  */
-             while (bits > 8)
+             while (bits >= 8)
                {
                  --pin;
                  bits -= 8;