On 1/3/19 11:44 PM, Jakub Jelinek wrote:
> Hi!
> 
> The prev_offset we push into the vector is supposed to be the end of
> the red zone for the variable, it needs to be ASAN_MIN_RED_ZONE_SIZE
> aligned, but by aligning it more we can end up with red zone with negative
> size.  E.g. on the testcase, we have initial frame_offset -8 (because of
> -fstack-protector guard), we align it to -32 first (required that the
> start and end of the var block is 32 byte aligned (4 byte aligned in shadow
> memory)).  The first variable needs 64 byte alignment, but is just 4 bytes,
> so the next after
>   offset = alloc_stack_frame_space (size, alignment);
> we end up with frame_offset (== offset) -64 and the start of red zone is
> after that 4 byte variable, i.e. at -60.  But the align_base tweak from
> -32 with 64 byte alignment gives -64.

Thank you Jakub for the patch.
I was also considering adding a sanity check that will ensure
the offsets in data->asan_vec are always in increasing order.
What do you think about it?

> 
> Now, the stack vars are sorted first by large vs. small alignment (not
> relevant to x86), then by size and only afterwards by alignment, so similar
> problems could appear if we have some large variable followed by > 32 byte
> aligned very small variable.
> 
> Fixed thusly, bootstrapped/regtested on x86_64-linux and i686-linux, ok for
> trunk?

I can add here that asan.exp tests work both on ppc64le-linux-gnu and 
ppc64-linux-gnu.
I'm going to trigger asan-bootstrap on one of them.

Martin

> 
> 2019-01-03  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR sanitizer/88619
>       * cfgexpand.c (expand_stack_vars): Only align prev_offset to
>       ASAN_MIN_RED_ZONE_SIZE, not to maximum of that and alignb.
> 
>       * c-c++-common/asan/pr88619.c: New test.
> 
> --- gcc/cfgexpand.c.jj        2019-01-01 12:37:17.328972145 +0100
> +++ gcc/cfgexpand.c   2019-01-03 14:11:16.209366858 +0100
> @@ -1130,7 +1130,7 @@ expand_stack_vars (bool (*pred) (size_t)
>                 prev_offset = frame_offset.to_constant ();
>               }
>             prev_offset = align_base (prev_offset,
> -                                     MAX (alignb, ASAN_MIN_RED_ZONE_SIZE),
> +                                     ASAN_MIN_RED_ZONE_SIZE,
>                                       !FRAME_GROWS_DOWNWARD);
>             tree repr_decl = NULL_TREE;
>             unsigned HOST_WIDE_INT size
> --- gcc/testsuite/c-c++-common/asan/pr88619.c.jj      2019-01-03 
> 14:16:00.779659964 +0100
> +++ gcc/testsuite/c-c++-common/asan/pr88619.c 2019-01-03 14:15:40.568994254 
> +0100
> @@ -0,0 +1,14 @@
> +/* PR sanitizer/88619 */
> +/* { dg-do compile { target fstack_protector } } */
> +/* { dg-options "-fstack-protector-strong -fsanitize=address" } */
> +
> +typedef int A __attribute__((aligned (64)));
> +
> +int
> +main ()
> +{
> +  A b;
> +  int *p = &b;
> +  *(p - 1) = 123;
> +  __builtin_alloca (b);
> +}
> 
>       Jakub
> 

Reply via email to