Another way people can approach this is to build the port with
-fstack-protector-all, and all it's dependencies.  The 1-byte
overflow may be easier to diagnose without retguard protection,
but the old school -all protector probably exposes it.

These days, -fstack-protector defaults to -fstack-protector-strong.
-strong is an innovation written by google staffers.  It (probably)
followed conversations I had with the years with some of them to improve
the original heuristic.  Dr. Etoh had written SSP to protect all
functions, but it was too expensive.  So in OpenBSD we went with only
protecting functions with >=16 bytes of local storage.  It was a middle
choice that got us progress.  Then other systems adopted the same
approach.  Over time, the compilers got better at tracking variable
types and dependencies and then google build -strong (search for blogs
discussing it), and we enabled this as the default.  The old school
stackprotector cookie method has the benefit that the debugger has an
easier time following traces.

Someone should compile the ports tree with -fstack-protector-all and
see what falls out.  Wait, don't just see, try to fix what you see :)

Christian Weisgerber <na...@mips.inka.de> wrote:

> 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