Commit Graph

1639 Commits

Author SHA1 Message Date
Mark Wielaard b9fd0eee50 libelf: Split checks for ehdr and shdr, drop phdr check in file_read_elf.
There are various places in the code that check whether mmapped structures
are correctly aligned (or ALLOW_UNALIGNED is set). Some of these checks
are asserts. Like the one in elf(32|64)_getshdr. We should not get into
that part of the code if the shdr scn structure was cached in elf_begin
because it was mmapped in and properly aligned.

These asserts could trigger because in elf_begin.c file_read_elf ()
all alignment checks were combined. So even though only one of the ehdr,
shdr or phdr structures were not properly aligned all structures would be
copied. Also the phdr structure was not even read in elf_begin, so the
alignment check was unnecessary.

This patch splits the alignment checks and reading of ehdr and shdr
structures into separate code paths. It also drops the phdr alignment
checks in elf_begin. Those phdr checks are done in elf(32|64)_getphdr
already.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-08 11:12:38 +02:00
Mark Wielaard 8aaf4fc46f libdwfl: Fix memory leak in __libdwfl_open_by_build_id.
commit c57829 introduced a memory leak by passing the path string to
strsep. strsep will change the given pointer and set it to NULL eventually.
Causing the original pointer to leak. Fix by passing a copy of the pointer
to strsep.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:52:29 +02:00
Mark Wielaard f17a9bbc29 Define MODVERSION in a more reproducable way.
We define MODVERSION to make sure the libebl backend modules match the
elfutils build when we dlopen them. Using hostname and date makes it very
hard to create reproducable builds. Define them a little more reproducable
using LIBEBL_SUBDIR, eu_version and ac_cv_build.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:52:29 +02:00
Mark Wielaard 170f1bb0a8 Fix sanitize-undefined config check. Don't ALLOW_UNALIGNED when checking.
The -fsanitize=undefined check need to use AC_LINK_IFELSE to make sure
libubsan is installed. When doing undefined checking we should disable
ALLOW_UNALIGNED memory accesses to catch issues where we do unaligned
accesses by accident.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:52:29 +02:00
Mark Wielaard 616489da50 libdwfl: Don't assume auxv or r_debug data is properly aligned in link_map.
core file data isn't guaranteed to be alligned properly. Use
read_(4|8)ubyte_unaligned_noncvt to read values, types and addresses.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:52:29 +02:00
Mark Wielaard 96f6c995ff libelf: Fix possible unbounded stack usage in load_shdr_wrlock.
When a copy needs to be made of the shdrs, allocate with malloc and free
after conversion instead of calling alloca.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:48:55 +02:00
Mark Wielaard 2ec5182478 libelf: Fix possible unbounded stack usage in getphdr_wrlock.
When a copy needs to be made of the phdrs, allocate with malloc and free
after conversion instead of calling alloca.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:48:55 +02:00
Mark Wielaard f78e864047 libelf: Fix unbounded stack usage in elf_getarsym for !ALLOW_UNALIGNED case.
The number of entries in the index can be large, don't use alloca to
read in temporary data, use malloc (which is freed after out).

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:48:55 +02:00
Mark Wielaard 0d528f9cef elfcmp: Don't call memcmp with possible NULL d_buf.
When d_size is zero d_buf might be NULL.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:44:59 +02:00
Mark Wielaard fc9b79400a libelf: Don't call memmove with possible NULL buffer.
When size is zero the buffer src and dest buffers might be NULL.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:44:59 +02:00
Mark Wielaard b4ad3c4b81 libelf: Don't call mempcpy with possible NULL d_buf.
When d_size is zero d_buf might be NULL. last_position doesn't need to be
updated in that case.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:44:59 +02:00
Mark Wielaard 5ad751b089 libdwfl: Check file_name is not NULL before calling canonicalize_file_name.
canonicalize_file_name is marked as taking a nonnull argument.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:44:59 +02:00
Mark Wielaard 7ec8d27033 tests: Always print reason when skipping test.
Make sure the reason a test is SKIPPED is added to the test-suite.log.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:41:20 +02:00
Mark Wielaard 4664fd5871 configure: Add check for bunzip2 and maintainer-mode tools.
Without bunzip2 make check cannot be run. To generate all files in
maintainer-mode flex and bison are needed. Otherwise check that
libdw/known-dwarf.h is already generated.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:41:19 +02:00
Mark Wielaard 5a47d469b5 libdw: Fix overflow in read_encoded_value for the DW_EH_PE_indirect case.
If we are going to dereference a pointer there should be at least enough
data to hold a pointer. Found by afl-fuzz.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-05 14:35:41 +02:00
Mark Wielaard 1ae83ee854 libdw: Fix overflow in read_encoded_value for the DW_EH_PE_indirect case.
If we are going to dereference a pointer there should be at least enough
data to hold a pointer. Found by afl-fuzz.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-06-01 10:34:11 +02:00
Mark Wielaard e115bda377 libdwfl: Check mod is not NULL in check_module.
check_module is called from dwfl_module_relocate_address and from
dwfl_module_address_section. Both could take a NULL Dwfl_Module if
an earlier error had occured. Make check_module return immediately
indicating an issue in that case.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:15:11 +02:00
Mark Wielaard 712f3c8930 config: Add -Wstack-usage=262144 (256K) warning check.
All library code now builds with this warning and -Werror enabled.
Add exceptions for most of the src tools (ldgeneric, readelf, nm, size,
strip, elflint, findtextrel, elfcmp objdump, ranlib, ar and unstrip).

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard e69f59c671 libdw: Limit stack usage of temporary dir, file and line lists.
Limit stack usage of lines with MAX_STACK_LINES, files with MAX_STACK_LINES
and dirs with MAX_STACK_DIRS. Calculate number of dirs needed first, then
create dirarray directly, without needing the next field. Free not stack
allocated lines and files at the end.

Use preallocated stack arrays for all instead of calling alloca to help
compiler see actual stack usage.

The current stack allocation limits are 4096 lines, 1024 files in 256 dirs
per CU. For GCC 4.8 libstdc++.so has on average 512 lines per CU.  With
these settings read_srclines uses max 228K of stack on x86_64.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard f592035ea1 libdwfl: Don't allocate phdrs and dyn on stack in link_map.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard f96ec4a9bb libdwfl: Don't allocate phdrs and dyn on stack in dwfl_segment_report_module.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard c4f133a956 libdwfl: find_debuginfo_in_patch don't alloca/strdupa strings of unknown size.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard c57829bb11 libdwfl: Reject very short or really large build-ids.
We cannot handle build-ids less than at least 3 or more than 64 bytes.
Very big build-ids, or very large debug search paths might have blown
up the stack.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard 9202fe132c libdwfl: Don't allocate all phdrs on the stack in elf_from_remote_memory.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard 08e5ae6fc8 libdwfl: Don't stack allocate alternate_name in dwfl_linux_kernel_find_elf.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard 251f1459aa libdwfl: Minimize stack usage in dwfl_linux_kernel_report_offline.
Don't stack allocate module name. Also fixes a latent bug (if the module
file didn't have a suffix - which is very unlikely) and an inefficiency.
We only need to substitue chars up to the suffix.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard 720f83a563 libdw: Fix possibly unbounded stack usage in __libdw_intern_expression.
Create a stack allocated array to hold locs. Allocate locs bigger than
the array with malloc and free them when done.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard 903924f054 libdwfl: Fix unbounded stack usage in find_prelink_address_sync.
Allocate phdr and shdr unions with malloc, not alloca. Free after use.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard be17786f9d libdwfl: Fix possible unbounded stack usage in cache_sections.
For modules with lots of sections cache_sections could blow up the stack
theoretically. Don't use alloca, but use malloc with explicit free.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard 390dd3d21c libebl: Don't blow up stack when processing large NT_GNU_ABI_TAG.
Normally an NT_GNU_ABI_TAG is large, just 4 words (16 bytes).
Only use stack allocated conversion buf for small (max 16 words) notes.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard df1708a2d6 libebl: Use static number for array stack allocation in openbackend.
Help the compiler see we stack allocate a small array.  Add assert to check
no machine prefix is ever larger than 16. Current maximum number is 7.
This prevents gcc warning about possible unbounded stack usage with
-Wstack-usage.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard e6261005ea libelf: Fix possible unbounded stack usage in updatefile.
Allocate shdr_data and scns with malloc, not alloca. Free after writing
section headers.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard 2e5df0c350 libelf: Fix possible unbounded stack usage in updatemmap.
Allocate temporary shdr storage with malloc, not alloca. Free after
writing section headers.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard bfb9a752c3 libelf: Fix possible unbounded stack usage in elf_getarsym.
The number of entries in the index can be large, don't use alloca to
read in temporary data, use malloc (and free after out).

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 23:04:31 +02:00
Mark Wielaard 6f2e64a03b addr2line: Set scopes to NULL after free in handle_address.
If dwarf_getscopes_die () fails then scopes might not be reset and we
could cause a double free.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 17:17:51 +02:00
Mark Wielaard b23a5b2dda addr2line: Add --pretty-print option to show all information on one line.
This adds an option --pretty-print to eu-addr2line to show all information
on one line and all inlines on a line of their own. This mimics the same
option from binutils addr2line, but without the short option variant -p.
Since we already use -p to select the process.

Example output:

eu-addr2line --pretty-print -s -i -f -C -p$(pidof firefox) 0x00007f368c6f8915
mozilla::ReentrantMonitor::Wait(unsigned int) at ReentrantMonitor.h:92
 (inlined by) mozilla::ReentrantMonitorAutoEnter::Wait(unsigned int) at ReentrantMonitor.h:190

A couple of tests were added to check the output matches that of
binutils addr2line.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 17:17:51 +02:00
Mark Wielaard cd2da6c37b addr2line: Add demangler support.
Makes the -C, --demangle option visible and implements it (ignoring the
demangle style argument). Adds a new test with sample output.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 17:17:51 +02:00
Mark Wielaard 70a504d1e1 addr2line: Add -a, --address. Print address before for each entry.
Adds test cases with sample output.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 17:17:51 +02:00
Mark Wielaard d76d73f490 addr2line: Always parse addresses as hex numbers.
We would sometimes interpret input addresses as decimal or octal.
That could be confusing and isn't what binutils addr2line does.
Be consistent and always treat input addresses as hex.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 17:17:51 +02:00
Mark Wielaard 472890f580 addr2line: Split options in input and output format groups.
This makes it clear that -j, --section=NAME is about how input is treated,
not how the output is formatted.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 17:17:51 +02:00
Mark Wielaard 77482c4bf6 libelf: Use posix_fallocate instead of ftruncate to extend ELF file.
This fixes an obscure SIGBUS error when using ELF_C_WRITE_MMAP on an ELF
file that needs extending when the underlying file system is (nearly) full.

Use posix_fallocate to make sure the file content is really there. Using
ftruncate might mean the file is extended, but space isn't allocated yet.
This might cause a SIGBUS once we write into the mmapped space and the disk
is full.

Using fallocate might fail on some file systems. posix_fallocate is
required to extend the file and allocate enough space even if the
underlying filesystem would normally return EOPNOTSUPP or the kernel
doesn't implement the fallocate syscall. Also posix_fallocate has been in
glibc since 2.1.94, while support for fallocate was only added in 2.10
and kernel 2.6.23.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 17:10:48 +02:00
Mark Wielaard 2b250b7597 configure: Add --enable-sanitize-undefined.
Now that we are -fsanitize=undefined clean make sure we keep it that way.

We do have to disable alignment checking. Because we might explicitly
use unaligned accesses (see ALLOW_UNALIGNED).

Rename DISTCHECK_CONFIGURE_FLAGS to AM_DISTCHECK_CONFIGURE_FLAGS, so the
user can override. And add --enable-sanitize-undefined.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-27 15:09:36 +02:00
Mark Wielaard c2297eab17 libelf: If e_phnum is zero then set e_phoff also to zero.
If phnum is zero make sure e_phoff is also zero and not some random value.
That would cause trouble in update_file. This could happen when ELF_F_LAYOUT
is set and the user copied over a ehdr from a bogus ELF file where the phdrs
are unreadable. In that case trying to write out the new ELF image would
crash trying to follow the bogus e_phdr value.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-18 15:48:04 +02:00
Mark Wielaard 6d93c8c46d strip: Harden against bogus input files. Don't leak tmp debug file on error.
There were various places where a bogus/unexpected input file would cause
eu-strip to crash. Also on an unexpected error eu-strip would leak the temp
debug file it was writing.

https://bugzilla.redhat.com/show_bug.cgi?id=1170810#c34

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-18 15:48:04 +02:00
Mark Wielaard c0748eff84 libelf: More checking of valid sh_addralign values.
There were two issues with bogus sh_addralign values. First we would only
check the individual Elf_Data d_align values were powerof2. But not the
actual shdr addralign value. This would cause an issue if the shdr addralign
was bigger than all of the individual d_align values. Then we could write
out a bogus (! powerof2) shdr addralign value for the sections. Secondly
when reading in the Elf_Data we would set the d_align value to the value
of the shdr addralign value. But we would not check it was valid at all.
In practice there are ELF files with incorrect sh_addralign values (they
are a powerof2, but aren't aligned to the ELF image offset). We would try
to fix that up in elf_update by adding extra padding. But this could bloat
the ELF image a lot for large alignment values. So for too large alignments
that are bigger than the offset in the ELF file clamp them to the offset
value. This could lead us to reject to write out the data again when the
offset was not a powerof2. But this will only happen for aligment values
bigger than 64. Which are uncommon in practice.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-18 15:48:04 +02:00
Mark Wielaard 458027d294 libelf: Make sure shdrs are valid before storing extended phnum in newphdr.
Creating phdr with more than PN_XNUM phnum requires a valid section zero
shdr to store the extended value. Make sure the shdrs are valid. Also fix
the error when count was too big to store by setting ELF_E_INVALID_INDEX
before failing.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-18 15:48:04 +02:00
Jonathan Lebon 987e3d722d dwarf_begin_elf: new error for compression failure
In order to provide better feedback to users, a distinction is made
between finding no dwarf info (E_NO_DWARF) and finding dwarf info but
which is compressed and failed to decompress (E_COMPRESSED_ERROR). This
can occur for example if elfutils was built without zlib support, or if
the compressed section is invalid.

Signed-off-by: Jonathan Lebon <jlebon@redhat.com>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-13 17:43:25 +02:00
Jonathan Lebon 90659075ad dwarf_begin_elf: decouple section searching from reading
To help legibility, we separate the section name matching from the
actual section reading. This also allows us to remove duplicate code in
cases of sections appearing twice or empty section data. There are no
changes in functionality. The indentation will be fixed in the next
commit, in the interest of keeping this commit easier to read.

Signed-off-by: Jonathan Lebon <jlebon@redhat.com>
Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-13 17:32:20 +02:00
Mark Wielaard a2b964c7db Always call gelf_fsize with EV_CURRENT as argument.
Don't trust the elf version given by the file. It could be completely
bogus. In which case gelf_fsize just returns zero. Which could cause
divide by zero errors.

https://bugzilla.redhat.com/show_bug.cgi?id=1170810#c34

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-13 16:31:52 +02:00
Mark Wielaard f085540301 libdwfl: Only intern CU when not EOF marker and cuoff points to a DIE.
We need to check the cuoff points to a real Dwarf_Die before trying to
intern the cu with tsearch. Otherwise bogus keys might end up in the
search tree with NULL cus. That will cause crashes in compare_cukey
during next insertion or deletion of cus. We also don't want to insert
the EOF marker and unconditionally tdestroy the lazy_cu_root. The EOF
could be caused by bad DWARF from a bogus agranges entry.

https://bugzilla.redhat.com/show_bug.cgi?id=1170810#c30

Signed-off-by: Mark Wielaard <mjw@redhat.com>
2015-05-12 16:54:05 +02:00