public inbox for elfutils@sourceware.org
 help / color / mirror / Atom feed
* [Bug libelf/28101] New: elf_strptr slow with address sanitizer, passes entire section range to memrchr.
@ 2021-07-19  7:43 jan.smets at nokia dot com
  2021-07-19  8:10 ` [Bug libelf/28101] " mark at klomp dot org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: jan.smets at nokia dot com @ 2021-07-19  7:43 UTC (permalink / raw)
  To: elfutils-devel

https://sourceware.org/bugzilla/show_bug.cgi?id=28101

            Bug ID: 28101
           Summary: elf_strptr slow with address sanitizer, passes entire
                    section range to memrchr.
           Product: elfutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: enhancement
          Priority: P2
         Component: libelf
          Assignee: unassigned at sourceware dot org
          Reporter: jan.smets at nokia dot com
                CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

This code block calls out to validate_str which calls to memrchr.
The to= is the size of the entire section.

I believe Address Sanitizer does validate the entire memory range. 
Passing the entire range to the memrchr null char check makes it very costly.


191   else if (likely (strscn->data_list_rear == NULL))
192     {
193       // XXX The above is currently correct since elf_newdata will
194       // make sure to convert the rawdata into the datalist if
195       // necessary. But it would be more efficient to keep the rawdata
196       // unconverted and only then iterate over the rest of the (newly
197       // added data) list.  Note that when the ELF file is mmapped
198       // rawdata_base can be set while rawdata.d hasn't been
199       // initialized yet (when data_read is zero). So we cannot just
200       // look at the rawdata.d.d_size.
201
202       /* Make sure the string is NUL terminated.  Start from the end,
203          which very likely is a NUL char.  */
204       if (likely (validate_str (strscn->rawdata_base, offset, sh_size)))
205         result = &strscn->rawdata_base[offset];
206       else
207         __libelf_seterrno (ELF_E_INVALID_INDEX);
208     }


* libelf compiled with HAVE_DECL_MEMRCHR (default)
* recent GCC toolchain (GCC6 and up)
* files themselves don't even need to be compiled with asan, just enabling it
at link time so the runtime wrapping/intercepting of libc et all fires.

Testcase:

test.c is attached.
Generate a source file with dummy symbols to populate the symbol table.


for i in {A..Z}{A..Z}{A..Z}{A..Z}; do echo "int sym$i;"; done > symbols.c
gcc -c symbols.c -o symbols.o
gcc -c test.c -o test.o -I /tmp/jan-test/elfutils/libelf/ #-fsanitize=address

gcc test.o symbols.o -o test  -l:libelf.a -L/tmp/jan-test/elfutils/libelf/  -lz
-fsanitize=address
echo -n "default asan:"
time ./test test

echo -n "asan disabled"
gcc test.o symbols.o -o test  -l:libelf.a -L/tmp/jan-test/elfutils/libelf/  -lz
time ./test test

I don't know of any ASAN_OPTIONS parameter that would change this behavior and
make it less strict.

On my machine the asan testcase takes 5+ sec, whereas the non-asan 0.04s.

Can this code please be optimized to reduce the range passed to memrchr?
Is this NUL check even required?

-- 
You are receiving this mail because:
You are on the CC list for the bug.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2021-07-19 13:58 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-19  7:43 [Bug libelf/28101] New: elf_strptr slow with address sanitizer, passes entire section range to memrchr jan.smets at nokia dot com
2021-07-19  8:10 ` [Bug libelf/28101] " mark at klomp dot org
2021-07-19  8:35 ` jan.smets at nokia dot com
2021-07-19 13:58 ` mark at klomp dot org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).