Since the introduction of retguard, devel/simulavr has continuously
failed to build on amd64.  This is actually a bug in devel/avr/gcc.
The problem was diagnosed early by mortimer@.  As I'm not making
any progress, I'm forwarding his analysis here to give other people
a chance to help out.

------------------------------------------------------------------------
Date: Wed, 9 May 2018 21:58:47 -0400
From: Todd Mortimer <t...@opennet.ca>
To: Christian Weisgerber <na...@mips.inka.de>
Cc: es...@openbsd.org
Subject: Re: Retguard needs a ports run

> build failure that happened again when I re-tried: devel/simulavr
>
> avr-gcc  -I. -I../src -I.     -g -Wall -mmcu=atmega128 -MT timer.o -MD -MP 
> -MF .deps/timer.Tpo -c -o timer.o timer.c
> avr-gcc: Internal error: Abort trap (program cc1)
>
> I'm skeptical that this has anything to do with retguard, but it
> is unexpected.

This isn't a retguard failure - it's a buffer overwrite by one. The
overwrite smashes the stack protector, so the Abort is coming from the
stack smash handler:

>>> bt
#0  thrkill () at -:3
#1  0x00000e789907db2c in __stack_smash_handler (func=<optimized out>, 
damaged=<optimized out>) at /usr/src/lib/libc/sys/stack_protector.c:79
#2  0x00000e7667e2bdb2 in df_record_exit_block_uses ()
#3  0x00000e7667e313b7 in df_update_exit_block_uses ()
#4  0x00000e7667e2f44f in df_update_entry_exit_and_calls ()
#5  0x00000e7667f0a95c in thread_prologue_and_epilogue_insns ()
#6  0x00000e7667f05524 in rest_of_handle_thread_prologue_and_epilogue ()
#7  0x00000e7667fa3213 in execute_one_pass ()
#8  0x00000e7667fa2e9f in execute_pass_list ()
#9  0x00000e7667fa2ec7 in execute_pass_list ()
#10 0x00000e7667fa2ec7 in execute_pass_list ()
#11 0x00000e76680ccea6 in tree_rest_of_compilation ()
#12 0x00000e766827ac77 in cgraph_expand_function ()
#13 0x00000e766827b541 in cgraph_assemble_pending_functions ()
#14 0x00000e766827a9bd in cgraph_finalize_function ()
#15 0x00000e7667d14a8b in finish_function ()
#16 0x00000e7667d83b2b in c_parser_declaration_or_fndef ()
#17 0x00000e7667d8276f in c_parser_external_declaration ()
#18 0x00000e7667d818b7 in c_parser_translation_unit ()
#19 0x00000e7667d81617 in c_parse_file ()
#20 0x00000e7667d73022 in c_common_parse_file ()
#21 0x00000e76680680d1 in compile_file ()
#22 0x00000e7668066f35 in do_compile ()
#23 0x00000e7668066bc9 in toplev_main ()
#24 0x00000e7667d9d4ff in main ()

I stepped through the code to see where it was dying. It's like this:

- df_record_exit_block_uses() has a buffer on the stack

- it calls df_exit_block_uses_collect(), which iterates through the buffer
  setting entries.

- Before returning, df_exit_block_uses_collect() calls
  df_canonize_collection_rec(), which null terminates the buffer, which
  happens to null terminate just past the end of the buffer, which just
  happens to be the stack cookie.

- The cookie check fails, and it dies.

So it seems that the way that retguard is responsible for this is
because retguard changes the stack frame layout a bit, and the stack
cookie happens to be immediately next to the buffer now, and now it gets
whacked. This shouldn't be too hard to patch - it's just a buffer
overflow.

Thanks again!

:-)
Todd

-- 
Christian "naddy" Weisgerber                          na...@mips.inka.de

Reply via email to