From: "jan.smets at nokia dot com" <sourceware-bugzilla@sourceware.org>
To: elfutils-devel@sourceware.org
Subject: [Bug libelf/28101] New: elf_strptr slow with address sanitizer, passes entire section range to memrchr.
Date: Mon, 19 Jul 2021 07:43:00 +0000 [thread overview]
Message-ID: <bug-28101-10460@http.sourceware.org/bugzilla/> (raw)
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.
next reply other threads:[~2021-07-19 7:43 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-19 7:43 jan.smets at nokia dot com [this message]
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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=bug-28101-10460@http.sourceware.org/bugzilla/ \
--to=sourceware-bugzilla@sourceware.org \
--cc=elfutils-devel@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).