This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Come up with --param asan-stack-small-redzone (PR sanitizer/81715).


On Wed, Sep 26, 2018 at 11:33:25AM +0200, Martin Liška wrote:
> 2018-09-26  Martin Liska  <mliska@suse.cz>
> 
> 	PR sanitizer/81715
> 	* asan.c (asan_shadow_cst): Remove.
> 	(asan_emit_redzone_payload): New.
> 	(asan_emit_stack_protection): Make it more
> 	flexible to support arbitrary size of red zones.
> 	* asan.h (ASAN_MIN_RED_ZONE_SIZE): New.
> 	(asan_var_and_redzone_size): Likewise.
> 	* cfgexpand.c (expand_stack_vars): Reserve size
> 	for stack vars according to asan_var_and_redzone_size.
> 	(expand_used_vars): Make smaller offset based
> 	on ASAN_SHADOW_GRANULARITY.
> 
> gcc/testsuite/ChangeLog:
> 
> 2018-09-26  Martin Liska  <mliska@suse.cz>
> 
> 	PR sanitizer/81715
> 	* c-c++-common/asan/asan-stack-small.c: New test.

Sorry for the delay.  I had a quick look.  Using:
struct S { char a[32]; };
void bar (void *, void *, void *, void *);

int
foo (void)
{
  struct S a, b, c, d;
  bar (&a, &b, &c, &d);
  return 0;
}

int
baz (void)
{
  char a;
  short b;
  int c;
  long long d;
  bar (&a, &b, &c, &d);
  return 0;
}
-O2 -fsanitize=address, I see that foo is identical before/after your patch,
perfect.
Looking at baz, I see issues though:
.LC2:
        .string "4 32 1 4 a:15 48 2 4 b:16 64 4 4 c:17 80 8 4 d:18"
...
        movq    %rbx, %rbp
        movl    $-3580, %edx
        movl    $-3085, %ecx
        movq    $1102416563, (%rbx)
        shrq    $3, %rbp
        movq    $.LC2, 8(%rbx)
        leaq    48(%rbx), %rsi
        leaq    32(%rbx), %rdi
        movq    $.LASANPC1, 16(%rbx)
        movw    %dx, 2147450888(%rbp)
        leaq    64(%rbx), %rdx
        movw    %cx, 2147450891(%rbp)
        leaq    80(%rbx), %rcx
        movl    $-235802127, 2147450880(%rbp)
        movl    $-234687999, 2147450884(%rbp)
        movb    $-13, 2147450893(%rbp)
        call    bar
        cmpq    %rbx, %r12
        jne     .L15
        movq    $0, 2147450880(%rbp)
        xorl    %eax, %eax
        movl    $0, 2147450888(%rbp)
        movw    %ax, 2147450892(%rbp)
So, looks like the shadow at (%rbx>>3)+0x7fff8000 is:
/ 2147450880(%rbp)
|           / 2147450884(%rbp)
|           |           / 2147450888(%rbp)
|           |           |           / 2147450892(%rbp)
|           |           |           |
f1 f1 f1 f1 01 f2 02 f2 04 f2 00 f3 f3 f3

Two problems, it uses unconditionally unaligned stores, without
checking if the target supports them at all (in this case it does).
And, it doesn't check if it wouldn't be more efficient to use
32-bit stores.  It isn't that we want the gaps to have whatever
value the shadow memory contained before, we want it to be 0 and just rely
on it being zero from earlier.
Another question is if it wouldn't be worth to ensure the variable area is
always a multiple of 32 bytes (thus the corresponding shadow always multiple
of 4 bytes).  Then, for this testcase, you'd store:
$-235802127, 2147450880(%rbp)	// 0xf1f1f1f1
$-234687999, 2147450884(%rbp)   // 0xf202f201
$-218041852, 2147450888(%rbp)   // 0xf300f204
$-202116109, 2147450892(%rbp)   // 0xf3f3f3f3
For the single char/short/int/long var in a function case you'd still emit
just f1 f1 f1 f1 0[1240] f3 f3 f3
and the number of final f3 bytes would be from 3 to 6 (or 2 to 5), 1 is
probably too few.

Rather than special-casing the two very small adjacent vars case,
just use a rolling handling of the shadow bytes, if you fill all 4,
emit immediately, otherwise queue later and flush if the next shadow offset
is outside of the 4 bytes.  Either always use SImode stores, or check rtx
costs; if the 32-bit constants you'd store is as expensive or less than the
16-bit or 8-bit constant, use 32-bit store, otherwise use a 16-bit or 8-bit
one.  If you want to complicate it further, allow unaligned stores on
targets that do allow them, but use them with care, if you could use same
amount of aligned stores with the same cost of constants, prefer aligned
ones.

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]