[Bug c/90376] New: spurious -Warray-bounds on memset() of several struct's subobjects

2019-05-07 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90376

Bug ID: 90376
   Summary: spurious -Warray-bounds on memset() of several
struct's subobjects
   Product: gcc
   Version: 9.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ryabinin.a.a at gmail dot com
  Target Milestone: ---

This is new on gcc 9.

# cat array_bounds.c

struct trace_iterator {
char a;
int seq;
long b;
};

void f(void)
{
static struct trace_iterator iter;
__builtin_memset(, 0,
sizeof(struct trace_iterator) -
__builtin_offsetof(struct trace_iterator, seq));

}

# gcc -O2 -c -Warray-bounds array_test.c
array_test.c: In function ‘f’:
array_test.c:12:2: warning: ‘__builtin_memset’ offset [9, 16] from the object
at ‘iter’ is out of the bounds of referenced subobject ‘seq’ with type ‘int’ at
offset 4 [-Warray-bounds]
   12 |  __builtin_memset(, 0,
  |  ^~
   13 |   sizeof(struct trace_iterator) -
  |   ~~~
   14 |   __builtin_offsetof(struct trace_iterator, seq));
  |   ~~~

[Bug sanitizer/84210] __ubsan_handle_builtin_unreachable shoun't be const

2018-02-05 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84210

--- Comment #2 from Andrey Ryabinin  ---
(In reply to Richard Biener from comment #1)
> Confirmed.  Note that I'm not sure it makes no sense - it just means the
> function has no side-effect besides not returning ;)
> 

Well, GCC docs say that const functions "have no effects except to return a
value" and "It does not make sense for a const function to return void."
I suppose that noreturn functions fells into the same category here as return
void functions.

Besides, __ubsan_handle_builtin_unreachable() does have side-effect, it prints
error.


> lib/ubsan.c is from the kernel I guess where you "copy" the attributes from
> sanitizer.def?
> 

Yes, lib/ubsan.c is kernel's implementation of libubsan. We don't exactly
'copy' attributes, but __ubsan_handle_builtin_unreachable() does have noreturn.
I've tried to add const to be consistent with GCC, but it become only worse:

../lib/ubsan.c:432:1: warning: ignoring attribute ‘noreturn’ in declaration of
a built-in function ‘__ubsan_handle_builtin_unreachable’ because it conflicts
with attribute ‘const’ [-Wattributes]
 {
 ^
: note: previous declaration here
../lib/ubsan.c:432:1: warning: ‘const’ attribute on function returning ‘void’
[-Wattributes]
../lib/ubsan.c:432:1: warning: ignoring attribute ‘const’ in declaration of a
built-in function ‘__ubsan_handle_builtin_unreachable’ because it conflicts
with attribute ‘noreturn’ [-Wattributes]
: note: previous declaration here


> GCC internally could also use "no vops" but you couldn't replicate that.
> 

We probably don't have to replicate all attributes. At least userspace libubsan
doesn't do that at all.

In fact we could workaround this warning simply by dropping noreturn:
http://lkml.kernel.org/r/20180202154813.1625742-1-a...@arndb.de

But, I'm thinking that there is something wrong in GCC, hence filed this bug.

> Not sure if it is/was important to have the function 'const'.

[Bug sanitizer/84210] New: __ubsan_handle_builtin_unreachable shoun't be const

2018-02-05 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84210

Bug ID: 84210
   Summary: __ubsan_handle_builtin_unreachable shoun't be const
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ryabinin.a.a at gmail dot com
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

Compiling the linux kernel with gcc-8 gives this warning:

lib/ubsan.c:432:1: error: ignoring attribute 'noreturn' in declaration of a
built-in function '__ubsan_handle_builtin_unreachable' because it conflicts
with attribute 'const' [-Werror=attributes]


It seems that GCC defines __ubsan_handle_builtin_unreachable with noreturn and
const attributes:

DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE,
  "__ubsan_handle_builtin_unreachable",
  BT_FN_VOID_PTR,
  ATTR_COLD_CONST_NORETURN_NOTHROW_LEAF_LIST)

And const doesn't make any sense for function that returns void or doesn't
return at all.
Shouldn't it be just ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST ?

[Bug sanitizer/81040] asan false negative if parameter of a global function passed by reference

2017-07-03 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81040

--- Comment #15 from Andrey Ryabinin  ---
(In reply to Martin Liška from comment #14)
> Fixed on trunk.

Thanks.

However there is slight problem with this. Instrumentation is missing without
-fsanitize-address-use-after-scope option.
IMO, it should depend only on --param asan-stack=1.

So the following doesn't produce any output:
gcc -fsanitize=address -fno-sanitize-address-use-after-scope -O2 asan_test.c &&
./a.out

Can we fix this?

[Bug sanitizer/81040] asan false negative if parameter of a global function passed by reference

2017-06-13 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81040

--- Comment #7 from Andrey Ryabinin  ---
(In reply to Martin Liška from comment #6)
> Can't see that clang++ is capable of catching your first test-case:
> 
> $ clang++ pr81040.cpp -fsanitize=address && ./a.out 
> pr81040.cpp:3:9: warning: expression result unused; assign into a variable
> to force a volatile load [-Wunused-volatile-lvalue]
> *(volatile int*)a;
> ^
> 1 warning generated.
> 

Try simply 'clang' without ++ 
Seems clang++ just optimize away unused volatile lvalue.

Or just make goo() to use *a, e.g.:
static __attribute__((noinline)) int goo(int *a)
{   
return *(volatile int*)a;   
}


> $ clang++ --version
> clang version 4.0.0 (tags/RELEASE_400/final 297347)
> Target: x86_64-unknown-linux-gnu
> Thread model: posix
> InstalledDir: /usr/bin

[Bug sanitizer/81040] asan false negative if parameter of a global function passed by reference

2017-06-13 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81040

--- Comment #4 from Andrey Ryabinin  ---
(In reply to Martin Liška from comment #3)
> As mentioned by Richard, currently ASAN is able to protect function
> variables that live on stack. In your case the function foo is called with
> constant that is then assigned a stack slot which we don't instrument with
> red zones.

Exactly, that's the problem. That stack slot should be instrumented with
redzones. Surely compiler is capable of doing this. Clang does this.
So I don't understand why you closed this as WONTFIX.

[Bug sanitizer/81040] New: asan false negative if parameter of a global function passed by reference

2017-06-09 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81040

Bug ID: 81040
   Summary: asan false negative if parameter of a global function
passed by reference
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ryabinin.a.a at gmail dot com
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

The following test case doesn't produce asan warning while it should.
For some reason gcc doesn't surround 'a' with redzones.

$ cat asan_test.c 

static __attribute__((noinline)) void goo(int *a)
{
*(volatile int*)a;
}

 __attribute__((noinline)) void foo(char a)
{
goo((int*));
}

int main()
{
foo(1);
return 0;
}

$ gcc -fsanitize=address -O2 asan_test.c 
$ ./a.out
$


Now, if we make foo() static, asan suddenly works:

$ cat asan_static_test.c 

static __attribute__((noinline)) void goo(int *a)
{
*(volatile int*)a;
}

static __attribute__((noinline)) void foo(char a)
{
goo((int*));
}

int main()
{
foo(1);
return 0;
}
$ gcc -fsanitize=address -O2 asan_static_test.c 
$ ./a.out 
=
==3278==ERROR: AddressSanitizer: stack-buffer-overflow on address
0x7ffc2e298480 at pc 0x0040083b bp 0x7ffc2e298440 sp 0x7ffc2e298438
READ of size 4 at 0x7ffc2e298480 thread T0
#0 0x40083a in goo (/home/andrew/linux/a.out+0x40083a)
#1 0x4008a0 in foo.constprop.0 (/home/andrew/linux/a.out+0x4008a0)
#2 0x4006e8 in main (/home/andrew/linux/a.out+0x4006e8)
#3 0x7ff179db971f in __libc_start_main (/lib64/libc.so.6+0x2071f)
#4 0x400738 in _start (/home/andrew/linux/a.out+0x400738)

Address 0x7ffc2e298480 is located in stack of thread T0 at offset 32 in frame
#0 0x40084f in foo.constprop.0 (/home/andrew/linux/a.out+0x40084f)

  This frame has 1 object(s):
[32, 33) 'a' <== Memory access at offset 32 partially overflows this
variable
HINT: this may be a false positive if your program uses some custom stack
unwind mechanism or swapcontext
  (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow
(/home/andrew/linux/a.out+0x40083a) in goo
Shadow bytes around the buggy address:
  0x15c4b040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x15c4b050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x15c4b060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x15c4b070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x15c4b080: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
=>0x15c4b090:[01]f4 f4 f4 f3 f3 f3 f3 00 00 00 00 00 00 00 00
  0x15c4b0a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x15c4b0b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x15c4b0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x15c4b0d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x15c4b0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:   00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:   fa
  Heap right redzone:  fb
  Freed heap region:   fd
  Stack left redzone:  f1
  Stack mid redzone:   f2
  Stack right redzone: f3
  Stack partial redzone:   f4
  Stack after return:  f5
  Stack use after scope:   f8
  Global redzone:  f9
  Global init order:   f6
  Poisoned by user:f7
  Container overflow:  fc
  Array cookie:ac
  Intra object redzone:bb
  ASan internal:   fe
  Left alloca redzone: ca
  Right alloca redzone:cb
==3278==ABORTING

[Bug sanitizer/69863] New: no_sanitize_address doesn't disable stack instrumentation

2016-02-18 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69863

Bug ID: 69863
   Summary: no_sanitize_address doesn't disable stack
instrumentation
   Product: gcc
   Version: 5.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ryabinin.a.a at gmail dot com
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org
  Target Milestone: ---

Attribute no_sanitize_address doesn't disable instrumentation completely.

Apparently no_sanitize_address only disables memory access checks, but it 
doesn't have influence on stack redzones. 
Regardless of this attribute gcc creates and poisons/unpoisons stack redzones.

$ cat no_sanitize_stack_test.c 

void g(int *a);

__attribute__((no_sanitize_address))
void func(void)
{
int a;
g();
}

$ gcc -fsanitize=address -c no_sanitize_stack_test.c && objdump -d
no_sanitize_stack_test.o

 :


  4d:   49 c1 ec 03 shr$0x3,%r12
  51:   41 c7 84 24 00 80 ffmovl   $0xf1f1f1f1,0x7fff8000(%r12)
  58:   7f f1 f1 f1 f1 
  5d:   41 c7 84 24 04 80 ffmovl   $0xf4f4f404,0x7fff8004(%r12)
  64:   7f 04 f4 f4 f4 
  69:   41 c7 84 24 08 80 ffmovl   $0xf3f3f3f3,0x7fff8008(%r12)
  70:   7f f3 f3 f3 f3 
  75:   64 48 8b 14 25 28 00mov%fs:0x28,%rdx

[Bug sanitizer/67513] ASAN: Not optimal shadow value check (unlikely condition checked in fast path)

2015-09-10 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67513

--- Comment #4 from Andrey Ryabinin  ---
(In reply to Andrey Ryabinin from comment #3)
> (In reply to Yury Gribov from comment #1)
> > (In reply to Andrey Ryabinin from comment #0)
> > > (shadow value is usually zero).
> > 
> > What makes you think so? AFAIU for less-than-8-byte scalars it's always
> > non-zero.
> 
> If 'a' is a pointer to an individual stack/global variable then yes, shadow
> will be non-zero.
> But if it's part of some array or a struct field, more likely shadow will be
> zero.
> So I'm not saying that we should blindly switch to non-zero test first, but
> it definitely worth trying.
> 
> > I vaguely remember than Kostya did something like this in Clang
> > case and it resulted in negligeable improvement.
> 
> clang (version 3.7.0 (tags/RELEASE_370/final))
> tests for non-zero first:
> 
this was a dump from slightly different test-case, here is correct one:

foo:# @foo
.cfi_startproc
# BB#0:
pushq   %rax
.Ltmp0:
.cfi_def_cfa_offset 16
movq%rdi, %rax
shrq$3, %rax
movb2147450880(%rax), %al
testb   %al, %al
jne .LBB0_1
.LBB0_3:
movb$0, (%rdi)
popq%rax
retq
.LBB0_1:
movl%edi, %ecx
andl$7, %ecx
movsbl  %al, %eax
cmpl%eax, %ecx
jl  .LBB0_3
# BB#2:
callq   __asan_report_store1
#APP
#NO_APP
.Lfunc_end0:
.size   foo, .Lfunc_end0-foo
.cfi_endproc


[Bug sanitizer/67513] ASAN: Not optimal shadow value check (unlikely condition checked in fast path)

2015-09-10 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67513

--- Comment #3 from Andrey Ryabinin  ---
(In reply to Yury Gribov from comment #1)
> (In reply to Andrey Ryabinin from comment #0)
> > (shadow value is usually zero).
> 
> What makes you think so? AFAIU for less-than-8-byte scalars it's always
> non-zero.

If 'a' is a pointer to an individual stack/global variable then yes, shadow
will be non-zero.
But if it's part of some array or a struct field, more likely shadow will be
zero.
So I'm not saying that we should blindly switch to non-zero test first, but it
definitely worth trying.

> I vaguely remember than Kostya did something like this in Clang
> case and it resulted in negligeable improvement.

clang (version 3.7.0 (tags/RELEASE_370/final))
tests for non-zero first:

foo:# @foo
.cfi_startproc
# BB#0:
pushq   %rax
.Ltmp0:
.cfi_def_cfa_offset 16
testl   %esi, %esi
je  .LBB0_4
# BB#1: # %.lr.ph
movq%rdi, %rax
shrq$3, %rax
movb2147450880(%rax), %al
testb   %al, %al
jne .LBB0_2
.LBB0_3:
movl$0, (%rdi)
.LBB0_4:
popq%rax
retq
.LBB0_2:
movl%edi, %ecx
andl$7, %ecx
addl$3, %ecx
movsbl  %al, %eax
cmpl%eax, %ecx
jl  .LBB0_3
# BB#5:
callq   __asan_report_store4
#APP
#NO_APP
.Lfunc_end0:
.size   foo, .Lfunc_end0-foo
.cfi_endproc


[Bug sanitizer/67513] New: ASAN: Not optimal shadow value check (unlikely condition checked in fast path)

2015-09-09 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67513

Bug ID: 67513
   Summary: ASAN: Not optimal shadow value check (unlikely
condition checked in fast path)
   Product: gcc
   Version: 5.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ryabinin.a.a at gmail dot com
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org
  Target Milestone: ---

Created attachment 36311
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=36311=edit
repro case

Consider following simple case:

void foo(unsigned int *a) {
*a = 0;
}

Compiling this with 'gcc -O2  -fsanitize=address asan_test.c -S -o -'
gave me the following code:

foo:
.LASANPC0:
.LFB0:
.cfi_startproc
movq%rdi, %rax
shrq$3, %rax
movzbl  2147450880(%rax), %edx
movq%rdi, %rax
andl$7, %eax
addl$3, %eax
cmpb%dl, %al
jl  .L2
testb   %dl, %dl
jne .L11
.L2:
movl$0, (%rdi)
ret
.L11:
pushq   %rax
.cfi_def_cfa_offset 16
call__asan_report_store4
.cfi_endproc


if I read this assembly correctly, GCC did something like this:

foo(addr):
{
if (((addr & 7) + 3) < *shadow)
goto access;

if (*shadow)
  report_error(addr);

access:
   *a = 0
return;
}

So the problem here is that check '((addr & 7) + 3) < *shadow)' is in the
fast-path, while it should be in a slow-path (shadow value is usually zero).


[Bug ipa/67368] Inlining failed due to no_sanitize_address and always_inline conflict

2015-09-08 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67368

Andrey Ryabinin  changed:

   What|Removed |Added

 CC||ryabinin.a.a at gmail dot com

--- Comment #3 from Andrey Ryabinin  ---
(In reply to Yury Gribov from comment #2)
> (In reply to Richard Biener from comment #1)
> > so it fails on purpose (not sure why though).  And it ignores always-inline.
> > I wonder if we should, for always-inline functions, inline anyway and output
> > a warning instead.
> 
> We prohibited this combination during ASan integration to kernel. Both
> always_inline and no_sanitize_address are strong requirements for compiler
> i.e. dropping any of these in favor of another would have unexpected effects
> and hurt usability.

Nope, it was prohibited because no_sanitize_address didn't work for inlined
function https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59600.


[Bug sanitizer/63802] UBSan doesn't catch misaligned access if address is 16-bytes (or more) aligned

2014-11-18 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63802

Andrey Ryabinin ryabinin.a.a at gmail dot com changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED

--- Comment #5 from Andrey Ryabinin ryabinin.a.a at gmail dot com ---
Fixed


[Bug sanitizer/63802] New: UBSan doesn't catch misaligned access if address is 16-bytes (or more) aligned

2014-11-10 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63802

Bug ID: 63802
   Summary: UBSan doesn't catch misaligned access if address is
16-bytes (or more) aligned
   Product: gcc
   Version: 5.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: ryabinin.a.a at gmail dot com
CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
jakub at gcc dot gnu.org, kcc at gcc dot gnu.org,
mpolacek at gcc dot gnu.org

Created attachment 33929
  -- https://gcc.gnu.org/bugzilla/attachment.cgi?id=33929action=edit
Repro case

Let's say we have struct that requires 64-bytes alignment.

struct test_struct {
  unsigned long a;
  int b;
} __attribute__((__aligned__(64)));


UBSan will not catch misaligned access if address of such struct is 16 bytes
aligned.

If address is not aligned to 16 bytes, UBSan will catch it, but alignment in
report is wrong (16 instead of 64):

misaligned_test.c:14:80: runtime error: member access within misaligned address
0x006011cf for type 'struct test_struct', which requires 16 byte alignment
0x006011cf: note: pointer points here
 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00
00 00 00 00  00 00 00
 ^


[Bug middle-end/61848] [5 Regression] a previous declaration causes the section attribute to be lost

2014-09-03 Thread ryabinin.a.a at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61848

--- Comment #8 from Andrey Ryabinin ryabinin.a.a at gmail dot com ---
Hi, may I ask what's the status of this?

Besides of section mismatches in linux kernel it also breaks kernel's modules.
Variable __this_module doesn't get into section .gnu.linkonce.this_module,
therefore module refuses to load.