On Sun, Jun 04, 2017 at 04:40:17AM -0400, Bryan Steele wrote:
> "As Shmuel reported in
> <https://gcc.gnu.org/ml/gcc-help/2017-03/msg00009.html>,
> on x86-64 small structures in automatic storage are aligned to 16 bytes.
> This seems to be because of a mix-up between bits and bytes in the i386
> target code.
> 
> * config/i386/i386.c (ix86_local_alignment): Align most aggregates
> of 16 bytes and more to 16 bytes, not those of 16 bits and more."
> 
> https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=b44e9be23d38be8997ae64d7509ac22cb4c556d6
> 
> It might be worth fixing this in ports gcc 4.9, found by tedu@ in 2014
> and committed by martynas@ to base gcc4 shortly later.
> 
> http://www.tedunangst.com/flak/post/my-stack-protector-wasnt-working
> http://marc.info/?l=openbsd-cvs&m=139895377300712&w=2
> http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/gnu/gcc/gcc/config/i386/i386.c.diff?r1=1.3&r2=1.4&f=h
> 
> -Bryan.
> 
> Index: Makefile
> ===================================================================
> RCS file: /cvs/ports/lang/gcc/4.9/Makefile,v
> retrieving revision 1.47
> diff -u -p -u -r1.47 Makefile
> --- Makefile  4 Mar 2017 21:59:55 -0000       1.47
> +++ Makefile  4 Jun 2017 08:36:12 -0000
> @@ -4,7 +4,7 @@ ONLY_FOR_ARCHS = amd64 arm hppa i386 mip
>  DPB_PROPERTIES = parallel
>  
>  V = 4.9.4
> -REVISION = 4
> +REVISION = 5
>  FULL_VERSION = $V
>  FULL_PKGVERSION = $V
>  
> Index: patches/patch-gcc_config_i386_i386_c
> ===================================================================
> RCS file: /cvs/ports/lang/gcc/4.9/patches/patch-gcc_config_i386_i386_c,v
> retrieving revision 1.4
> diff -u -p -u -r1.4 patch-gcc_config_i386_i386_c
> --- patches/patch-gcc_config_i386_i386_c      1 Sep 2016 17:30:33 -0000       
> 1.4
> +++ patches/patch-gcc_config_i386_i386_c      4 Jun 2017 08:36:12 -0000
> @@ -1,6 +1,6 @@
>  $OpenBSD: patch-gcc_config_i386_i386_c,v 1.4 2016/09/01 17:30:33 pascal Exp $
> ---- gcc/config/i386/i386.c.orig      Mon Aug  1 18:03:41 2016
> -+++ gcc/config/i386/i386.c   Sat Aug  6 19:19:04 2016
> +--- gcc/config/i386/i386.c.orig      Mon Aug  1 12:03:41 2016
> ++++ gcc/config/i386/i386.c   Sun Jun  4 04:30:01 2017
>  @@ -2307,6 +2307,8 @@ struct ix86_frame
>     HOST_WIDE_INT reg_save_offset;
>     HOST_WIDE_INT sse_reg_save_offset;
> @@ -18,13 +18,22 @@ $OpenBSD: patch-gcc_config_i386_i386_c,v
>     frame->nregs = ix86_nsaved_regs ();
>     frame->nsseregs = ix86_nsaved_sseregs ();
>   
> -@@ -10903,6 +10906,9 @@ ix86_expand_prologue (void)
> -       m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET;
> +@@ -10904,6 +10907,9 @@ ix86_expand_prologue (void)
>         m->fs.realigned = true;
>       }
> -+
> + 
>  +  if (warn_stack_larger_than && frame.local_size > stack_larger_than_size)
>  +    warning (OPT_Wstack_larger_than_, "stack usage is %ld bytes", 
> frame.local_size);
> - 
> ++
>     int_registers_saved = (frame.nregs == 0);
>     sse_registers_saved = (frame.nsseregs == 0);
> + 
> +@@ -26860,7 +26866,7 @@ ix86_local_alignment (tree exp, enum machine_mode 
> mode
> +                != TYPE_MAIN_VARIANT (va_list_type_node)))
> +        && TYPE_SIZE (type)
> +        && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
> +-       && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 16
> ++       && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 128
> +            || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128)
> +     return 128;
> +     }

This will probably require library and ports bumps, but here is
an example to better demonstrate the issue:

#include <stdio.h>
#include <string.h>

int main()
{
        char buf[15];
        strcpy(buf, "1234567890abcdef");
        printf("%s", buf);
}

# base gcc 4.2.1

$ gcc ssp-test.c -o ssp-test
/tmp//cc6vEhU3.o: In function `main':
ssp-test.c:(.text+0x21): warning: warning: strcpy() is almost always misused, 
please use strlcpy()
$ ./ssp-test
Abort trap

# base clang 4.0.0

$ /usr/bin/clang ssp-test.c -o ssp-test-clang1
/tmp/ssp-test-3faff4.o: In function `main':
ssp-test.c:(.text+0x31): warning: warning: strcpy() is almost always misused, pl
ease use strlcpy()
$ ./ssp-test-clang1
Abort trap

# ports clang 4.0.0

$ /usr/local/bin/clang ssp-test.c -o ssp-test-clang2
/tmp/ssp-test-f372af.o: In function `main':
ssp-test.c:(.text+0x31): warning: warning: strcpy() is almost always misused, pl
ease use strlcpy()
$ ./ssp-test-clang2
Abort trap

# ports egcc 4.9.4

$ egcc ssp-test.c -o ssp-test-egcc # ???
$ ./ssp-test-egcc
1234567890abcdef $
$ egcc -fno-builtin-strcpy ssp-test.c -o ssp-test-egcc
/tmp//ccU4UBvd.o: In function `main':
ssp-test.c:(.text+0x24): warning: warning: strcpy() is almost always misused, 
please use strlcpy()
$ ./ssp-test-egcc
1234567890abcdef $
$ readelf -a ssp-test-egcc | grep smash
000000200fc8  000f00000007 R_X86_64_JUMP_SLO 0000000000000000 
__stack_smash_handler + 0
    15: 0000000000000000   281 FUNC    GLOBAL DEFAULT  UND __stack_smash_handler
    30: 0000000000000000   281 FUNC    GLOBAL DEFAULT  UND 
__stack_smash_handler$

Reply via email to