Monday, June 05, 2017

Re: PATCH: Fix SSP on amd64 for ports gcc 4.9

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$

No comments:

Post a Comment