Re: pushed: Add support for DWARF-based fixed point types

Simon Marchi
2020-11-22T20:11:13Z

On 2020-11-22 9:00 a.m., Joel Brobecker wrote:
> I've been able to reproduce the problem, including with a GDB
> built at -O0. In order to do so, I had to use the system GCC,
> though. Before that, I was using AdaCore's version of GCC and
> couldn't reproduce with that.
>
> I'm out of time for this weekend, unfortunately, so it's at the top
> of my TODO for next weekend.

I didn't find the root cause (and whether GDB using GMP wrong or if it
is a bug in GMP (less likely)), but here's what I found.

Building both GDB and GMP with ASan makes the issue more obvious:

Running selftest gdb_mpq_write_fixed_point.
=================================================================
==3672064==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd6de06d08 at pc 0x7f185073086d bp 0x7ffd6de068a0 sp 0x7ffd6de06890
WRITE of size 8 at 0x7ffd6de06d08 thread T0
#0 0x7f185073086c in __gmpz_export /home/smarchi/src/gmp-6.2.0+dfsg/mpz/export.c:103
#1 0x557c2db68395 in gdb_mpz::write(unsigned char*, int, bfd_endian, bool) const /home/smarchi/src/binutils-gdb/gdb/gmp-utils.c:80
#2 0x557c2db68d02 in gdb_mpq::write_fixed_point(unsigned char*, int, bfd_endian, bool, gdb_mpq const&) const /home/smarchi/src/binutils-gdb/gdb/gmp-utils.c:144
#3 0x557c2ed2f796 in write_fp_test /home/smarchi/src/binutils-gdb/gdb/unittests/gmp-utils-selftests.c:405
#4 0x557c2ed2f949 in gdb_mpq_write_fixed_point /home/smarchi/src/binutils-gdb/gdb/unittests/gmp-utils-selftests.c:426
#5 0x557c300b280c in selftests::simple_selftest::operator()() const /home/smarchi/src/binutils-gdb/gdbsupport/selftest.cc:43
#6 0x557c300b22e2 in selftests::run_tests(gdb::array_view<char const* const>) /home/smarchi/src/binutils-gdb/gdbsupport/selftest.cc:99
#7 0x557c2dfce6c2 in maintenance_selftest /home/smarchi/src/binutils-gdb/gdb/maint.c:1026
#8 0x557c2d3dbe12 in do_const_cfunc /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:95
#9 0x557c2d3eb02d in cmd_func(cmd_list_element*, char const*, int) /home/smarchi/src/binutils-gdb/gdb/cli/cli-decode.c:2181
#10 0x557c2eb6e985 in execute_command(char const*, int) /home/smarchi/src/binutils-gdb/gdb/top.c:668
#11 0x557c2dfaa4c9 in catch_command_errors /home/smarchi/src/binutils-gdb/gdb/main.c:448
#12 0x557c2dfaacf0 in execute_cmdargs /home/smarchi/src/binutils-gdb/gdb/main.c:533
#13 0x557c2dfae6b1 in captured_main_1 /home/smarchi/src/binutils-gdb/gdb/main.c:1203
#14 0x557c2dfaebc5 in captured_main /home/smarchi/src/binutils-gdb/gdb/main.c:1224
#15 0x557c2dfaecad in gdb_main(captured_main_args*) /home/smarchi/src/binutils-gdb/gdb/main.c:1249
#16 0x557c2cdd0311 in main /home/smarchi/src/binutils-gdb/gdb/gdb.c:32
#17 0x7f184f9850b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#18 0x557c2cdd00ed in _start (/home/smarchi/build/binutils-gdb-all-targets/gdb/gdb+0x4a2e0ed)

Address 0x7ffd6de06d08 is located in stack of thread T0 at offset 104 in frame
#0 0x557c2ed2f669 in write_fp_test /home/smarchi/src/binutils-gdb/gdb/unittests/gmp-utils-selftests.c:393

This frame has 2 object(s):
[32, 64) 'v' (line 402)
[96, 104) 'buf' (line 399) <== Memory access at offset 104 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/smarchi/src/gmp-6.2.0+dfsg/mpz/export.c:103 in __gmpz_export

We pass mpz_export a buffer of 8 bytes (statically allocated in
write_fp_test), but GMP decides it needs to write 16 bytes, hence the
overflow.

I tried to read the GMP doc, but I am familiar with its concepts, so I
don't really understand if we are using the API correctly or not.

For reference this is how I configured libgmp:

./configure '--prefix=/tmp/gmp-install' 'CFLAGS=-g3 -O0 -fsanitize=address' 'CXXFLAGS=-g3 -O0 -fsanitize=address' 'LDFLAGS=-fsanitize=address'

Simon