[Bug sanitizer/86755] New: [ASAN] Libasan failed to be build for arm with -mthumb and -fno-omit-frame-pointer

2018-07-31 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86755

Bug ID: 86755
   Summary: [ASAN] Libasan failed to be build for arm with -mthumb
and -fno-omit-frame-pointer
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: d.khalikov at partner dot samsung.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: ---

Created attachment 44471
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44471=edit
Reduced test case

GCC fails to build libasan with -mthumb and -fno-omit-frame-pointer

../../../../libsanitizer/sanitizer_common/sanitizer_linux.cc: In function
'__sanitizer::uptr __sanitizer::internal_clone(int (*)(void*), void*, int,
void*, int*, void*, int*)':
../../../../libsanitizer/sanitizer_common/sanitizer_linux.cc:1540:1: error: r7
cannot be used in asm here
 }

The problem is inside internal_clone function defined for arm.

Reduced test case:

$cat clone.cc
#define __NR_clone 120
#define __NR_exit 1

using uptr = unsigned int;
unsigned int EINVAL = 1;
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr) {
  unsigned int res;
  if (!fn || !child_stack)
return -EINVAL;
  child_stack = (char *)child_stack - 2 * sizeof(unsigned int);
  ((unsigned int *)child_stack)[0] = (uptr)fn;
  ((unsigned int *)child_stack)[1] = (uptr)arg;
  register int r0 __asm__("r0") = flags;
  register void *r1 __asm__("r1") = child_stack;
  register int *r2 __asm__("r2") = parent_tidptr;
  register void *r3 __asm__("r3") = newtls;
  register int *r4 __asm__("r4") = child_tidptr;
  register int r7 __asm__("r7") = __NR_clone;

#if __ARM_ARCH > 4 || defined (__ARM_ARCH_4T__)
# define ARCH_HAS_BX
#endif
#if __ARM_ARCH > 4
# define ARCH_HAS_BLX
#endif

#ifdef ARCH_HAS_BX
# ifdef ARCH_HAS_BLX
#  define BLX(R) "blx "  #R "\n"
# else
#  define BLX(R) "mov lr, pc; bx " #R "\n"
# endif
#else
# define BLX(R)  "mov lr, pc; mov pc," #R "\n"
#endif

  __asm__ __volatile__(
   /* %r0 = syscall(%r7 = SYSCALL(clone),
*   %r0 = flags,
*   %r1 = child_stack,
*   %r2 = parent_tidptr,
*   %r3  = new_tls,
*   %r4 = child_tidptr)
*/

   /* Do the system call */
   "swi 0x0\n"

   /* if (%r0 != 0)
*   return %r0;
*/
   "cmp r0, #0\n"
   "bne 1f\n"

   /* In the child, now. Call "fn(arg)". */
   "ldr r0, [sp, #4]\n"
   "ldr ip, [sp], #8\n"
   BLX(ip)
   /* Call _exit(%r0). */
   "mov r7, %7\n"
   "swi 0x0\n"
   "1:\n"
   "mov %0, r0\n"
   : "=r"(res)
   : "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r7),
 "i"(__NR_exit)
   : "memory");
  return res;
} 


$armv7l-linux-gnueabi-g++ -o clone.s clone.cc -fno-omit-frame-pointer -mthumb
-S
clone.cc: In function ‘uptr internal_clone(int (*)(void*), void*, int, void*,
int*, void*, int*)’:
clone.cc:70:1: error: r7 cannot be used in asm here

Regarding to arm ABI, r7 register is using for syscall number, r0 for return
value, and r1 - r6 for syscall arguments, by the way r7 for arm with THUMB2
mode is using as frame pointer and it looks like we have a conflict in this
case. As far as I understood, GCC has a special check inside IRA 
if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM)), which
does not allow to have frame pointer register as clobber register. 

In other way, there is no issue with clang:
clang++ -target armv7l -S -o clone.s  clone.cc -mthumb -fno-omit-frame-pointer

So, looks like we can save syscall number in r8 register, move it to r7 before
we the interruption, and restore the value in the parent task. 

 register int r8 __asm__("r8") = __NR_clone;

  __asm__ __volatile__(
   /* %r0 = syscall(%r7 = SYSCALL(clone),

[Bug other/86198] Libbacktrace does not properly work with ".note.gnu.build-id" section

2018-06-21 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86198

Denis Khalikov  changed:

   What|Removed |Added

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

--- Comment #5 from Denis Khalikov  ---
Fixed on trunk.

[Bug other/86198] Libbacktrace does not properly work with ".note.gnu.build-id" section

2018-06-19 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86198

--- Comment #2 from Denis Khalikov  ---
Looks like that feature was implemented by this patch:
https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blobdiff;f=bfd/opncls.c;h=b4d4dcf64643145e71e70dba29cd8208c945ddec;hp=10684d2682da7623f4b2f3426eaa2d2ba0cd85b0;hb=2425a30e406a0523020b7e70abb864a06a45bb97;hpb=620214f742f7816e2844e1bb7f78a7a684431927

As I understood that code right, it takes "error" branch if size of the section
less than 0x24.

if (size < 0x24)
{
  bfd_set_error (bfd_error_invalid_operation);
  return NULL;
}

The libbacktrace instead verifies the section to be less than 0x24, should we
change it

from:

2871   && shdr->sh_size < 12 + ((note->namesz + 3) & ~ 3) +
note->descsz)

to:

2871   && shdr->sh_size == 12 + ((note->namesz + 3) & ~ 3) +
note->descsz)

?

[Bug other/86198] New: Libbacktrace does not properly work with ".note.gnu.build-id" section

2018-06-18 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86198

Bug ID: 86198
   Summary: Libbacktrace does not properly work with
".note.gnu.build-id" section
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: other
  Assignee: unassigned at gcc dot gnu.org
  Reporter: d.khalikov at partner dot samsung.com
  Target Milestone: ---

An error happens when libbacktrace is reading ".note.gnu.build-id" section and
effects the feature which allows to read stripped debuginfo with build-id.

Steps to reproduce:
(I will use libasan in my test case, because it's easy and libbacktrace is a
default symbolizer for libasan in GCC).

1.$cat a.cc
int main () {
  int *ptr = new int[1];
  return ptr[1];
}

2.$g++ -o a a.cc -fsanitize=address -g 
-Wl,--build-id=0x0123456789abcdef0123456789abcdef01234567

3.$objcopy --only-keep-debug a a.debug

4.$strip a

5. In this step we need a superuser rights:
#mkdir /usr/lib/debug/.build-id/01
#ln -s  `pwd`/a.debug
/usr/lib/debug/.build-id/01/23456789abcdef0123456789abcdef01234567.debug

6. ./a

output:
...
#0 0x4007cf  (/path/to/exe/a+0x4007cf)
...

The problem at the libbacktrace/elf.c line 2871

2866   buildid_view_valid = 1;
2867   note = (const b_elf_note *) buildid_view.data;
2868   if (note->type == NT_GNU_BUILD_ID
2869   && note->namesz == 4
2870   && strncmp (note->name, "GNU", 4) == 0
2871   && shdr->sh_size < 12 + ((note->namesz + 3) & ~ 3) +
note->descsz)
2872 {
2873   buildid_data = >name[0] + ((note->namesz + 3) & ~ 3);
2874   buildid_size = note->descsz;
2875 }
2876 }

The size for the ".note.gnu.build-id" section by default is 36 bytes (12 + 4 +
20)
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/developer_guide/compiling-build-id

So, the cmp on line 2871 should be changed from less to less or equal

2871   && shdr->sh_size <= 12 + ((note->namesz + 3) & ~ 3) +
note->descsz)

[Bug sanitizer/80414] [UBSAN] segfault with -fsanitize=undefined

2018-06-18 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80414

Denis Khalikov  changed:

   What|Removed |Added

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

--- Comment #2 from Denis Khalikov  ---
Fixed.

[Bug sanitizer/86090] [ASAN] ASAN does not properly configure libbacktrace.

2018-06-14 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86090

Denis Khalikov  changed:

   What|Removed |Added

 Status|NEW |RESOLVED
 Resolution|--- |FIXED

--- Comment #4 from Denis Khalikov  ---
Fixed on trunk.

[Bug sanitizer/86090] New: [ASAN] ASAN does not properly configure libbacktrace.

2018-06-08 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86090

Bug ID: 86090
   Summary: [ASAN] ASAN does not properly configure libbacktrace.
   Product: gcc
   Version: 9.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: d.khalikov at partner dot samsung.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: ---

Created attachment 44252
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44252=edit
libsanitizer.patch

Since sanitizers build libbacktrace from source, sanitizer's configure should 
check for lstat and readlink function directly, because by default libbacktrace
uses dummy versions which return -1 and therefore could not symbolize stripped
debuginfo with gnu-debuglink.

Steps to reproduce:

$g++ --version
output:
g++ (GCC) 9.0.0 20180606 (experimental)

$cat test.cc
int main () { int *ptr = new int[1]; return ptr[1]; }
$g++ -o test test.cc -fsanitize=address -g
$objcopy --only-keep-debug test test.debug
$strip -g test
$objcopy --add-gnu-debuglink=test.debug test
./test

output:
...
#0 0x4007af in main (/path/to/exe/test+0x4007af)
...

The backtrace is not symbolized.

Possible patch is attached.

[Bug sanitizer/81923] [ASAN] gcc emites wrong odr asan instrumentation for glibc

2017-08-31 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81923

--- Comment #8 from Denis Khalikov  ---
Works for me.
Thanks.

[Bug sanitizer/81923] [ASAN] gcc emites wrong odr asan instrumentation for glibc

2017-08-28 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81923

--- Comment #3 from Denis Khalikov  ---
Created attachment 42064
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=42064=edit
temp.S

[Bug sanitizer/81923] [ASAN] gcc emites wrong odr asan instrumentation for glibc

2017-08-28 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81923

--- Comment #2 from Denis Khalikov  ---
confgiure flags:

configure_flags="--prefix=/usr --without-cvs --without-selinux
--enable-stackguard-randomization --enable-obsolete-rpc
--disable-sanity-checks"

cc1 invocation:

/home/denis/gcc-build-trunk/libexec/gcc/x86_64-linux-gnu/8.0.0/cc1 -quiet -v -I
programs -I ../include -I /home/denis/glibc-2.24-build/build/locale -I
/home/denis/glibc-2.24-build/build -I ../sysdeps/unix/sysv/linux/x86_64/64 -I
../sysdeps/unix/sysv/linux/x86_64 -I ../sysdeps/unix/sysv/linux/x86 -I
../sysdeps/unix/sysv/linux/wordsize-64 -I ../sysdeps/x86_64/nptl -I
../sysdeps/unix/sysv/linux/include -I ../sysdeps/unix/sysv/linux -I
../sysdeps/nptl -I ../sysdeps/pthread -I ../sysdeps/gnu -I ../sysdeps/unix/inet
-I ../sysdeps/unix/sysv -I ../sysdeps/unix/x86_64 -I ../sysdeps/unix -I
../sysdeps/posix -I ../sysdeps/x86_64/64 -I ../sysdeps/x86_64/fpu/multiarch -I
../sysdeps/x86_64/fpu -I ../sysdeps/x86/fpu/include -I ../sysdeps/x86/fpu -I
../sysdeps/x86_64/multiarch -I ../sysdeps/x86_64 -I ../sysdeps/x86 -I
../sysdeps/ieee754/ldbl-96 -I ../sysdeps/ieee754/dbl-64/wordsize-64 -I
../sysdeps/ieee754/dbl-64 -I ../sysdeps/ieee754/flt-32 -I
../sysdeps/wordsize-64 -I ../sysdeps/ieee754 -I ../sysdeps/generic -I .. -I
../libio -I . -imultiarch x86_64-linux-gnu -MD
/home/denis/glibc-2.24-build/build/locale/SYS_libc.d -MF
/home/denis/glibc-2.24-build/build/locale/SYS_libc.os.dt -MP -MT
/home/denis/glibc-2.24-build/build/locale/SYS_libc.os -D
COMPLOCALEDIR="/usr/lib/locale" -D LOCALE_ALIAS_PATH="/usr/share/locale" -D
_LIBC_REENTRANT -D MODULE_NAME=libc -D PIC -D SHARED -include
/home/denis/glibc-2.24-build/build/libc-modules.h -include
../include/libc-symbols.h SYS_libc.c -quiet -dumpbase SYS_libc.c -mtune=generic
-march=x86-64 -auxbase-strip
/home/denis/glibc-2.24-build/build/locale/SYS_libc.os -g -O2 -Wall -Wundef
-Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Wno-error
-std=gnu11 -version -fgnu89-inline -fmerge-all-constants -frounding-math -fPIC
-ftls-model=initial-exec -fsanitize=address -fno-omit-frame-pointer --param
asan-use-after-return=0 -o temp.s

as invocation:
as -o temp.o temp.S

I also attached file after cc1 stage.

[Bug sanitizer/81923] New: [ASAN] gcc emites wrong odr asan instrumentation for glibc

2017-08-22 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81923

Bug ID: 81923
   Summary: [ASAN] gcc emites wrong odr asan instrumentation for
glibc
   Product: gcc
   Version: 8.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: d.khalikov at partner dot samsung.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: ---

Hello,
I'm currently working on enabling the build of glibc with ASan instrumentation
and facing this type of error:

/tmp/ccKWa1tS.s: Assembler messages:
/tmp/ccKWa1tS.s:20: Error: junk at end of line, first unrecognized character is
`*'
/tmp/ccKWa1tS.s:21: Error: junk at end of line, first unrecognized character is
`*'
/tmp/ccKWa1tS.s:23: Error: unrecognized symbol type ""
/tmp/ccKWa1tS.s:23: Error: junk at end of line, first unrecognized character is
`*'
/tmp/ccKWa1tS.s:24: Error: expected comma after name `__odr_asan.' in .size
directive
/tmp/ccKWa1tS.s:25: Error: invalid character '*' in mnemonic
/tmp/ccKWa1tS.s:53: Error: invalid operands (*UND* and .rodata sections) for
`*'

As far as I understood, the KASAN disables this type of instrumentation:

2567 static bool
2568 asan_needs_odr_indicator_p (tree decl)
2569 {
2570   /* Don't emit ODR indicators for kernel because:
2571  a) Kernel is written in C thus doesn't need ODR indicators.
2572  b) Some kernel code may have assumptions about symbols containing
specific
2573 patterns in their names.  Since ODR indicators contain original
names
2574 of symbols they are emitted for, these assumptions would be broken
for
2575 ODR indicator symbols.  */
2576   return (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS)
2577   && !DECL_ARTIFICIAL (decl)
2578   && !DECL_WEAK (decl)
2579   && TREE_PUBLIC (decl));
2580 }

Could it be some solution for glibc ? Or may be "compile time" flag.
Thanks.

[Bug sanitizer/81081] [ASAN] ASAN is not properly calling libbacktrace to symbolize program written on assembler

2017-06-16 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81081

--- Comment #9 from Denis Khalikov  ---
I've added patch for review 
https://reviews.llvm.org/D34149

[Bug sanitizer/77631] no symbols in backtrace shown by ASan when debug info is split

2017-06-16 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77631

Denis Khalikov  changed:

   What|Removed |Added

  Attachment #41478|0   |1
is obsolete||

--- Comment #10 from Denis Khalikov  ---
Created attachment 41574
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41574=edit
patch for PR sanitizer/77631

[Bug sanitizer/81081] [ASAN] ASAN is not properly calling libbacktrace to symbolize program written on assembler

2017-06-13 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81081

--- Comment #7 from Denis Khalikov  ---
Thanks, I was mistaken, fix should be in the libbacktrace.

[Bug sanitizer/81081] [ASAN] ASAN is not properly calling libbacktrace to symbolize program written on assembler

2017-06-13 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81081

--- Comment #5 from Denis Khalikov  ---
As I understood libbacktrace has two main calls to symbolize pc.

1. backtrace_pcinfo 

/* Given a PC, find the file name, line number, and function name.  */
164 
165 int
166 backtrace_pcinfo (struct backtrace_state *state, uintptr_t pc,
167   backtrace_full_callback callback,
168   backtrace_error_callback error_callback, void *data)
169 {

which initializing data with filename, line number and function name from
debuginfo sections

817   if (!backtrace_dwarf_add (state, base_address,
818 sections[DEBUG_INFO].data,
819 sections[DEBUG_INFO].size,
820 sections[DEBUG_LINE].data,
821 sections[DEBUG_LINE].size,
822 sections[DEBUG_ABBREV].data,
823 sections[DEBUG_ABBREV].size,
824 sections[DEBUG_RANGES].data,
825 sections[DEBUG_RANGES].size,
826 sections[DEBUG_STR].data,
827 sections[DEBUG_STR].size,
828 ehdr.e_ident[EI_DATA] == ELFDATA2MSB,
829 error_callback, data, fileline_fn))
830 goto fail;
831 
832   *found_dwarf = 1;

179 /* Given a PC, find the symbol for it, and its value.  */

2. backtrace_syminfo

int
182 backtrace_syminfo (struct backtrace_state *state, uintptr_t pc,
183backtrace_syminfo_callback callback,
184backtrace_error_callback error_callback, void *data)
185 {


Which is using only symbol table to intialize specific data. No debug info
needed.

748   if (!elf_initialize_syminfo (state, base_address,
749symtab_view.data, symtab_shdr->sh_size,
750strtab_view.data, strtab_shdr->sh_size,
751error_callback, data, sdata))


Those two calls using in function

156 bool LibbacktraceSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack)
{
157   SymbolizeCodeCallbackArg data;
158   data.first = stack;
159   data.last = stack;
160   data.frames_symbolized = 0;
161   backtrace_pcinfo((backtrace_state *)state_, addr,
SymbolizeCodePCInfoCallback,
162ErrorCallback, );
163   if (data.frames_symbolized > 0)
164 return true;
165   backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback,
166 ErrorCallback, );
167   return (data.frames_symbolized > 0);
168 }

with two callback:
1.
106 extern "C" {
107 static int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr,
108const char *filename, int lineno,
109const char *function) {
110   SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;
111   if (function) {
112 AddressInfo *info = cdata->get_new_frame(addr);
113 info->function = DemangleAlloc(function, /*always_alloc*/ true);
114 if (filename)
115   info->file = internal_strdup(filename);
116 info->line = lineno;
117 cdata->frames_symbolized++;
118   }
119   return 0;
120 }


2.122 static void SymbolizeCodeCallback(void *vdata, uintptr_t addr,
123   const char *symname, uintptr_t,
uintptr_t) {
124   SymbolizeCodeCallbackArg *cdata = (SymbolizeCodeCallbackArg *)vdata;
125   if (symname) {
126 AddressInfo *info = cdata->get_new_frame(addr);
127 info->function = DemangleAlloc(symname, /*always_alloc*/ true);
128 cdata->frames_symbolized++;
129   }
130 }

In my case we have partially valid data with line number, filename but we don't
have valid function name because debuginfo doesn't provide 
DW_TAG_subprogram and libbacktrace can not find valid symbol for specific
address, 
but this symbol was read from symbol table and have valid data.

My point is to read all data we have from first callback and if we don't have 
valid function name we assume that pc is not properly symbolized and we go
to bactrace_syminfo which will read symbol data and increment 

cdata->frames_symbolized++;

In case those two functions using completely different data to generate
backtrace.
Thanks.

[Bug sanitizer/81081] [ASAN] ASAN is not properly calling libbacktrace to symbolize program written on assembler

2017-06-13 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81081

--- Comment #3 from Denis Khalikov  ---
This fix
111   AddressInfo *info = cdata->get_new_frame(addr);
112   if (filename)
113 info->file = internal_strdup(filename);
114   info->line = lineno;
115   if (function) {
116 info->function = DemangleAlloc(function, /*always_alloc*/ true);
117 cdata->frames_symbolized++;
118   }
119   return 0;
120 }

solve my problem.

As far as I understood this chages should be made in llvm asan/

Should I send the patch Phabricator for review.

[Bug sanitizer/81081] New: [ASAN] ASAN is not properly calling libbacktrace to symbolize program written on assembler

2017-06-13 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81081

Bug ID: 81081
   Summary: [ASAN] ASAN is not properly calling libbacktrace to
symbolize program written on assembler
   Product: gcc
   Version: 7.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: d.khalikov at partner dot samsung.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: ---

Hello everyone,
I've faced a situation with ASan and program which were written on assembler
with debug info generated by "as".

In this case asan can't properly render symbolic info for that kind of program.

Steps to reproduce:

1.For test purpose we can generate assembler code by gcc from c code.

$cat test.c
int main() {
 int ptr = 0x01;
 int value = *(int *) ptr;
 return 0;
}

/gcc-build-trunk/libexec/gcc/x86_64-linux-gnu/7.1.1/cc1 -quiet -v -imultiarch
x86_64-linux-gnu test.c -quiet -dumpbase test.c -mtune=generic -march=x86-64
-auxbase test -version -o test.S

2. Assemble the code and generate debug info. 
as -v --64 -o test.o test.S -gdwarf-2

3.Link the program.

/gcc-build-trunk/libexec/gcc/x86_64-linux-gnu/7.1.1/collect2 -plugin
/gcc-build-trunk/libexec/gcc/x86_64-linux-gnu/7.1.1/liblto_plugin.so
-plugin-opt=/gcc-build-trunk/libexec/gcc/x86_64-linux-gnu/7.1.1/lto-wrapper
-plugin-opt=-fresolution=/tmp/ccuSSiyf.res -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s
--eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o
test /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o
/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1/crtbegin.o
-L/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1
-L/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1/../../../../lib64
-L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu
-L/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1/../../.. test.o -lgcc
--as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed
/gcc-build-trunk/lib/gcc/x86_64-linux-gnu/7.1.1/crtend.o
/usr/lib/x86_64-linux-gnu/crtn.o

4.Set LD_PRELOAD to look for segfault.

$export LD_PRELOAD=/lib64/libasan.so
$./test

#0 0x4004dd in main (test+0x4004dd)

As we can see symbolizer does not render the line number and filename, but
.debug_info section inside the file.

Looks like this happens because "as" can not generate dwarf tag
(DW_TAG_subprogram)
which consist address and name of the function.

In this case libbacktrace can't find function for specific address and call
callback with last param == NULL, which represents the name of the function:

return callback (data, pc, ln->filename, ln->lineno, NULL);

but filename and line number have a valid data.

The callback for backtrace_pcinfo check function and in case value is  NULL
assumes that other data is not valid.

111   if (function) {
112 AddressInfo *info = cdata->get_new_frame(addr);
113 info->function = DemangleAlloc(function, /*always_alloc*/ true);
114 if (filename)
115   info->file = internal_strdup(filename);
116 info->line = lineno;
117 cdata->frames_symbolized++;
118   }
119   return 0;

LibbacktraceSymbolizer::SymbolizePC function
skips execution to backtrace_syminfo and this function can symbolize address by
data from symbol table in elf file without debuginfo section.

So, should the callback be like this:  

111   AddressInfo *info = cdata->get_new_frame(addr);
112   if (filename)
113 info->file = internal_strdup(filename);
114   info->line = lineno;
115   if (function) {
116 info->function = DemangleAlloc(function, /*always_alloc*/ true);
117 cdata->frames_symbolized++;
118   }
119   return 0;
120 }

Thanks.

[Bug sanitizer/77631] no symbols in backtrace shown by ASan when debug info is split

2017-06-06 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77631

Denis Khalikov  changed:

   What|Removed |Added

  Attachment #40963|0   |1
is obsolete||

--- Comment #9 from Denis Khalikov  ---
Created attachment 41478
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41478=edit
patch for PR sanitizer/77631

Hello everyone,
I updated the patch.

List of implemented functionality:

 1. Reading .note.gnu.build-id section.
  a. Parsing section data.

 2. Reading.gnu_debuglink section.
  a. Parsing section data.
  b. Verifying crc32 sum.

 3. Searching for separate debug info file.
  a. /usr/lib/debug/.build-id
  b. /path/to/executable
  c. /path/to/executable/.debug
  d. /usr/lib/debug/path/to/executable


This patch works for me.
Anyway still waiting for review:
https://gcc.gnu.org/ml/gcc-patches/2017-05/msg01462.html

[Bug sanitizer/80414] New: [UBSAN] segfault with -fsanitize=undefined

2017-04-12 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80414

Bug ID: 80414
   Summary: [UBSAN] segfault with -fsanitize=undefined
   Product: gcc
   Version: 7.0.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: sanitizer
  Assignee: unassigned at gcc dot gnu.org
  Reporter: d.khalikov at partner dot samsung.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 41191
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41191=edit
patch

Hello everyone.

I got segfault on 32 bit host with -fsanitize=undefined

My test case:

# cat test.c 

int main()
{
  long long offset = 10;
  char array[10];
  char c = array[offset];
  return 0;
}

# gcc -o test test.c -fsanitize=undefined -static-libubsan
# ./test

That happens while checking for bounds-strict option on 32 bit host.

As i can see gcc push value of the index to the stack before call 
__ubsan_handle_out_of_bounds

 67 subl$44, %esp
 68 movl$10, -32(%ebp)
 69 movl$0, -28(%ebp)
 70 movl-32(%ebp), %ebx
 71 movl-28(%ebp), %esi
 72 movl%ebx, %eax
 73 cmpl$9, %eax
 74 jbe .L2
 75 subl$8, %esp
 76 pushl   %eax
 77 pushl   $.Lubsan_data0
 78 call__ubsan_handle_out_of_bounds

instead clang push address of that index

 15 movl$10, -32(%ebp)
 16 movl-28(%ebp), %eax
 17 movl-32(%ebp), %ecx
 18 movl%ecx, %edx
 19 cmpl$10, %edx
 20 movl%eax, -44(%ebp) # 4-byte Spill
 21 movl%ecx, -48(%ebp) # 4-byte Spill
 22 jb  .LBB0_2
 23 # BB#1:
 24 leal.L__unnamed_1, %eax
 25 leal-40(%ebp), %ecx
 26 movl-48(%ebp), %edx # 4-byte Reload
 27 movl%edx, -40(%ebp)
 28 movl-44(%ebp), %esi # 4-byte Reload
 29 movl%esi, -36(%ebp)
 30 movl%eax, (%esp)
 31 movl%ecx, 4(%esp)
 32 calll   __ubsan_handle_out_of_bounds

In this case fix should be in IR generation for
__ubsan_handle_out_of_bounds.

Looks like tree val should be generated from original tree 
index and not from tree index which 
were converted to bound type.

diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 17965ef..c56f376 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -672,7 +672,8 @@ ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)

   /* Pick up the arguments of the UBSAN_BOUNDS call.  */
   tree type = TREE_TYPE (TREE_TYPE (gimple_call_arg (stmt, 0)));
-  tree index = gimple_call_arg (stmt, 1);
+  tree index, orig_index;
+  index = orig_index = gimple_call_arg (stmt, 1);
   tree orig_index_type = TREE_TYPE (index);
   tree bound = gimple_call_arg (stmt, 2);

@@ -708,9 +709,9 @@ ubsan_expand_bounds_ifn (gimple_stmt_iterator *gsi)
  ? BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS
  : BUILT_IN_UBSAN_HANDLE_OUT_OF_BOUNDS_ABORT;
   tree fn = builtin_decl_explicit (bcode);
-  tree val = force_gimple_operand_gsi (gsi, ubsan_encode_value (index),
-  true, NULL_TREE, true,
-  GSI_SAME_STMT);
+  tree val
+   = force_gimple_operand_gsi (gsi, ubsan_encode_value (orig_index), true,
+   NULL_TREE, true, GSI_SAME_STMT);
   g = gimple_build_call (fn, 2, data, val);
 }
   gimple_set_location (g, loc);

I attached patch.
Tests with make check RUNTESTFLAGS="ubsan.exp" passed for x86 32bit 
and 64 bit host.

[Bug sanitizer/77631] no symbols in backtrace shown by ASan when debug info is split

2017-03-14 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77631

--- Comment #7 from Denis Khalikov  ---
Thomas, before verifying i should fix issues from the list,
https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00735.html

[Bug sanitizer/77631] no symbols in backtrace shown by ASan when debug info is split

2017-03-13 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77631

Denis Khalikov  changed:

   What|Removed |Added

 CC||d.khalikov at partner dot 
samsung.
   ||com

--- Comment #5 from Denis Khalikov  ---
Yes,i sent to gcc-patc...@gcc.gnu.org.

https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00660.html

[Bug sanitizer/77631] no symbols in backtrace shown by ASan when debug info is split

2017-03-13 Thread d.khalikov at partner dot samsung.com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77631

--- Comment #3 from Denis Khalikov  ---
Created attachment 40963
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40963=edit
patch for PR sanitizer/77631

Hello everyone, i have a patch for this issue.
(see attachment PR_sanitizer_77631)

List of implemented functionality:

1.Reading .gnu_debuglink section from ELF file:
 a. Reading name of debug info file.
 b. Verifying crc32 sum.

2. Searching for separate debug info file from paths: 
 a. /usr/lib/debug/path/to/executable
 b. /path/to/executable
 c. /path/to/executable/.debug

Assumed that debug info file generated by objcopy from binutils.

objcopy --only-keep-debug foo foo.debug
strip -g foo
objcopy --add-gnu-debuglink=foo.debug foo