[Bug libdw/26773] sleb128 values near INT64_MAX/MIN not correctly read

mark at klomp dot org sourceware-bugzilla@sourceware.org
Fri Oct 23 16:08:52 GMT 2020


--- Comment #4 from Mark Wielaard <mark at klomp dot org> ---
(In reply to Josh Stone from comment #2)
> (In reply to Tom Tromey from comment #1)
> > This limits the number of bytes read-- but it seems like
> > it maybe ought to read until the first byte without the
> > high bit set.
> Beware, golang just dealt with a CVE for reading unlimited varints:
> https://github.com/golang/go/issues/40618
> (But the context is different since that's used in stuff like protocol
> buffers that may be streamed.)

Note that there are two "limits" in play here. For the normal get_sleb128
(__libdw_get_sleb128) variant we already require that and end pointer is
provided, which we won't move past. We require the caller to make sure we can
read at least the first byte. For the get_sleb128_unchecked
(__libdw_get_sleb128_unchecked) variant we assume the called already knows
there is a valid sleb128 at the given address, so we don't require an end
pointer and can just read till the end (first byte that doesn't have the high
bit set).

The other limit is that we only read as many bytes that can "fit" the type.
That is the "step limit" which is given by len_leb128 (int64_t) (or
__libdw_max_len_uleb128/__libdw_max_len_sleb128 for the unchecked variant).
This limits makes sure we don't "overflow" the int64_t or uint64_t. So we
normally only read 10 bytes anyway.

The bug is in "the other limit". For signed types we subtract 1 to make sure we
didn't shift into the sign bit. But that means we can only read up to 9 bytes
of the sleb128 and will fail (return INT64_MAX and leave the addr pointer at
the last byte instead of consuming it).

I think Tom's suggestion to use an unsigned type for the sleb128 calculation
and then cast it to int64_t when done is the correct fix.

You are receiving this mail because:
You are on the CC list for the bug.

More information about the Elfutils-devel mailing list