[Bug c/90376] New: spurious -Warray-bounds on memset() of several struct's subobjects
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(&iter.seq, 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(&iter.seq, 0, | ^~ 13 | sizeof(struct trace_iterator) - | ~~~ 14 | __builtin_offsetof(struct trace_iterator, seq)); | ~~~
[Bug sanitizer/84210] __ubsan_handle_builtin_unreachable shoun't be const
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
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
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
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
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
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*)&a); } 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*)&a); } 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
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(&a); } $ 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)
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)
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)
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&action=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
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
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63802 Andrey Ryabinin changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED --- Comment #5 from Andrey Ryabinin --- Fixed
[Bug sanitizer/63802] New: UBSan doesn't catch misaligned access if address is 16-bytes (or more) aligned
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=33929&action=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
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61848 --- Comment #8 from Andrey Ryabinin --- 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.