This patch from pgerell at GitHub adds some casts to libbacktrace to
avoid undefined shifts. These shifts are OK on all real systems but
may as well get it right. Bootstrapped and ran libbacktrace tests on
x86_64-pc-linux-gnu. Committed to mainline.
Ian
libbacktrace: add casts to avoid undefined shifts
Patch from pgerell@github.
* elf.c (elf_fetch_bits): Add casts to avoid potentially shifting
a value farther than its type size.
(elf_fetch_bits_backward): Likewise.
(elf_uncompress_lzma_block): Likewise.
(elf_uncompress_lzma): Likewise.
db23cdf5d7b714d1ca7fe649cdd2a8aced383aac
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index a450f3535c6..d766fa41a61 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -1147,7 +1147,10 @@ elf_fetch_bits (const unsigned char **ppin, const
unsigned char *pinend,
next = __builtin_bswap32 (next);
#endif
#else
- next = pin[0] | (pin[1] << 8) | (pin[2] << 16) | (pin[3] << 24);
+ next = ((uint32_t)pin[0]
+ | ((uint32_t)pin[1] << 8)
+ | ((uint32_t)pin[2] << 16)
+ | ((uint32_t)pin[3] << 24));
#endif
val |= (uint64_t)next << bits;
@@ -1198,7 +1201,10 @@ elf_fetch_bits_backward (const unsigned char **ppin,
next = __builtin_bswap32 (next);
#endif
#else
- next = pin[0] | (pin[1] << 8) | (pin[2] << 16) | (pin[3] << 24);
+ next = ((uint32_t)pin[0]
+ | ((uint32_t)pin[1] << 8)
+ | ((uint32_t)pin[2] << 16)
+ | ((uint32_t)pin[3] << 24));
#endif
val <<= 32;
@@ -5872,10 +5878,10 @@ elf_uncompress_lzma_block (const unsigned char
*compressed,
/* The byte at compressed[off] is ignored for some
reason. */
- code = ((compressed[off + 1] << 24)
- + (compressed[off + 2] << 16)
- + (compressed[off + 3] << 8)
- + compressed[off + 4]);
+ code = ((uint32_t)(compressed[off + 1] << 24)
+ + ((uint32_t)compressed[off + 2] << 16)
+ + ((uint32_t)compressed[off + 3] << 8)
+ + (uint32_t)compressed[off + 4]);
off += 5;
/* This is the main LZMA decode loop. */
@@ -6198,10 +6204,10 @@ elf_uncompress_lzma_block (const unsigned char
*compressed,
return 0;
}
computed_crc = elf_crc32 (0, uncompressed, uncompressed_offset);
- stream_crc = (compressed[off]
- | (compressed[off + 1] << 8)
- | (compressed[off + 2] << 16)
- | (compressed[off + 3] << 24));
+ stream_crc = ((uint32_t)compressed[off]
+ | ((uint32_t)compressed[off + 1] << 8)
+ | ((uint32_t)compressed[off + 2] << 16)
+ | ((uint32_t)compressed[off + 3] << 24));
if (computed_crc != stream_crc)
{
elf_uncompress_failed ();
@@ -6336,10 +6342,10 @@ elf_uncompress_lzma (struct backtrace_state *state,
/* Before that is the size of the index field, which precedes the
footer. */
- index_size = (compressed[offset - 4]
- | (compressed[offset - 3] << 8)
- | (compressed[offset - 2] << 16)
- | (compressed[offset - 1] << 24));
+ index_size = ((size_t)compressed[offset - 4]
+ | ((size_t)compressed[offset - 3] << 8)
+ | ((size_t)compressed[offset - 2] << 16)
+ | ((size_t)compressed[offset - 1] << 24));
index_size = (index_size + 1) * 4;
offset -= 4;