[PATCH] Fix section corruption bug
by Thilo Schulz
Hi,
When adding data to existing sections in ELF files, libelf may corrupt
those sections, i.e. overwrite the existing data if certain conditions are
met.
If an Elf_Scn structure has seen a call to elf_rawdata(scn) before but no
call to elf_getdata(scn), scn->read_data flag is set, but not
scn->data_list_rear.
Thus, elf_newdata(scn) incorrectly detects a "new user added section" when
really it is a section with live, valid data that will be overwritten by
elf_update(), corrupting the section.
This patch fixes this incorrect behaviour.
Signed-off-by: Thilo Schulz <thilo(a)tjps.eu>
---
libelf/elf_newdata.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libelf/elf_newdata.c b/libelf/elf_newdata.c
index 90d1813..f90eb0a 100644
--- a/libelf/elf_newdata.c
+++ b/libelf/elf_newdata.c
@@ -64,7 +64,7 @@ elf_newdata (Elf_Scn *scn)
rwlock_wrlock (scn->elf->lock);
- if (scn->data_read && scn->data_list_rear == NULL)
+ if (scn->data_read && scn->data_list_rear == NULL && !scn->rawdata.s)
{
/* This means the section was created by the user and this is the
first data. */
--
1.7.10.4
9 years, 1 month
[PATCH] readelf: Fix overflow check in handle_sysv_hash64.
by Mark Wielaard
Since all values are 64bit, not 32bit as in other hashes, we need to
explicitly check for overflow.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 4 ++++
src/readelf.c | 6 ++++--
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index d3828d9..0819c1e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,7 @@
+2014-11-30 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (handle_sysv_hash64): Fix overflow check.
+
2014-11-28 Mark Wielaard <mjw(a)redhat.com>
* readelf.c (handle_relocs_rel): Don't reuse destshdr to store
diff --git a/src/readelf.c b/src/readelf.c
index 69ae5d0..89b1754 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3055,8 +3055,10 @@ handle_sysv_hash64 (Ebl *ebl, Elf_Scn *scn, GElf_Shdr *shdr, size_t shstrndx)
Elf64_Xword nbucket = ((Elf64_Xword *) data->d_buf)[0];
Elf64_Xword nchain = ((Elf64_Xword *) data->d_buf)[1];
- uint64_t used_buf = (2ULL + nchain + nbucket) * sizeof (Elf64_Xword);
- if (used_buf > data->d_size)
+ uint64_t maxwords = data->d_size / sizeof (Elf64_Xword);
+ if (maxwords < 2
+ || maxwords - 2 < nbucket
+ || maxwords - 2 - nbucket < nchain)
goto invalid_data;
Elf64_Xword *bucket = &((Elf64_Xword *) data->d_buf)[2];
--
1.9.3
9 years, 4 months
[PATCH] libdwfl: Check relocations don't overlap ELF ehdr, shdrs or phdrs.
by Mark Wielaard
American Fuzzy Lop (afl-fuzz) has an habit of generating ELF files
with relocations that when applied (or removed/cleared) change one
of the in-memory ELF headers. There does not seem to be a valid reason
for having section data that contain relocations or to which relocations
are applied to overlap with one of the headers.
If either the section that needs the relocation applied, or the
section that the relocations come from overlap one of the ehdrs,
shdrs or phdrs data then refuse to do the relocations. We update
both section data. It isn't illegal for ELF section data to overlap
the header data, but updating the (relocation) data might corrupt
the in-memory libelf headers causing strange corruptions or errors.
Also check offset + size of a relocation doesn't overflow.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdwfl/ChangeLog | 6 ++++++
libdwfl/relocate.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 52 insertions(+), 1 deletion(-)
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 5876fcc..03faecf 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-29 Mark Wielaard <mjw(a)redhat.com>
+
+ * relocate.c (relocate_section): Check relocation section and target
+ section data don't overlap any of the ELF headers.
+ (relocate): Check for offset + size overflow.
+
2014-11-22 Mark Wielaard <mjw(a)redhat.com>
* link_map.c (consider_executable): Use elf_getphdrnum.
diff --git a/libdwfl/relocate.c b/libdwfl/relocate.c
index 52b7b5e..4fc0956 100644
--- a/libdwfl/relocate.c
+++ b/libdwfl/relocate.c
@@ -297,6 +297,51 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
if (tdata == NULL)
return DWFL_E_LIBELF;
+ /* If either the section that needs the relocation applied, or the
+ section that the relocations come from overlap one of the ehdrs,
+ shdrs or phdrs data then we refuse to do the relocations. It
+ isn't illegal for ELF section data to overlap the header data,
+ but updating the (relocation) data might corrupt the in-memory
+ libelf headers causing strange corruptions or errors. */
+ if (unlikely (shdr->sh_offset < ehdr->e_ehsize
+ || tshdr->sh_offset < ehdr->e_ehsize))
+ return DWFL_E_BADELF;
+
+ GElf_Off shdr_start = ehdr->e_shoff;
+ size_t shnums;
+ if (elf_getshdrnum (relocated, &shnums) < 0)
+ return DWFL_E_LIBELF;
+ /* Overflows will have been checked by elf_getshdrnum/get|rawdata. */
+ GElf_Off shdr_end = shdr_start + shnums * ehdr->e_shentsize;
+ if (unlikely ((shdr->sh_offset >= shdr_start
+ && shdr->sh_offset < shdr_end)
+ || (shdr->sh_offset + shdr->sh_size >= shdr_start
+ && shdr->sh_offset + shdr->sh_size < shdr_end)
+ || (tshdr->sh_offset >= shdr_start
+ && tshdr->sh_offset < shdr_end)
+ || (tshdr->sh_offset + tshdr->sh_size >= shdr_start
+ && tshdr->sh_offset + tshdr->sh_size < shdr_end)))
+ return DWFL_E_BADELF;
+
+ GElf_Off phdr_start = ehdr->e_phoff;
+ size_t phnums;
+ if (elf_getphdrnum (relocated, &phnums) < 0)
+ return DWFL_E_LIBELF;
+ if (phdr_start != 0 && phnums != 0)
+ {
+ /* Overflows will have been checked by elf_getphdrnum/get|rawdata. */
+ GElf_Off phdr_end = phdr_start + phnums * ehdr->e_phentsize;
+ if (unlikely ((shdr->sh_offset >= phdr_start
+ && shdr->sh_offset < phdr_end)
+ || (shdr->sh_offset + shdr->sh_size >= phdr_start
+ && shdr->sh_offset + shdr->sh_size < phdr_end)
+ || (tshdr->sh_offset >= phdr_start
+ && tshdr->sh_offset < phdr_end)
+ || (tshdr->sh_offset + tshdr->sh_size >= phdr_start
+ && tshdr->sh_offset + tshdr->sh_size < phdr_end)))
+ return DWFL_E_BADELF;
+ }
+
/* Apply one relocation. Returns true for any invalid data. */
Dwfl_Error relocate (GElf_Addr offset, const GElf_Sxword *addend,
int rtype, int symndx)
@@ -365,7 +410,7 @@ relocate_section (Dwfl_Module *mod, Elf *relocated, const GElf_Ehdr *ehdr,
return DWFL_E_BADRELTYPE;
}
- if (offset + size > tdata->d_size)
+ if (offset > tdata->d_size || tdata->d_size - offset < size)
return DWFL_E_BADRELOFF;
#define DO_TYPE(NAME, Name) GElf_##Name Name;
--
1.9.3
9 years, 4 months
[PATCH] readelf: Always print INVALID SECTION if destshdr is NULL for relocation
by Mark Wielaard
We already checked this in all other cases except for the special case
of relocs in statically_linked executables. Found with afl.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 6 +++++
src/readelf.c | 77 +++++++++++++++++++++++++++++++++++++++++------------------
2 files changed, 60 insertions(+), 23 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index a6d18b5..072146a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-28 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (handle_relocs_rel): Print INVALID SECTION if destshdr
+ is NULL also for statically_linked relocations.
+ (handle_relocs_rela): Likewise.
+
2014-11-26 Mark Wielaard <mjw(a)redhat.com>
* readelf.c (print_debug_aranges_section): Cast Dwarf_Word length
diff --git a/src/readelf.c b/src/readelf.c
index cd15e4c..6060851 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1857,17 +1857,32 @@ handle_relocs_rel (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
}
if (is_statically_linked > 0 && shdr->sh_link == 0)
- printf ("\
- %#0*" PRIx64 " %-20s %*s %s\n",
- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
- ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
- /* Avoid the leading R_ which isn't carrying any
- information. */
- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
- buf, sizeof (buf)) + 2
- : gettext ("<INVALID RELOC>"),
- class == ELFCLASS32 ? 10 : 18, "",
- elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ {
+ if (unlikely (destshdr == NULL))
+ printf (" %#0*" PRIx64 " %-20s %*s <%s %ld>\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : gettext ("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, "",
+ gettext ("INVALID SECTION"),
+ (long int) (sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx));
+ else
+ printf (" %#0*" PRIx64 " %-20s %*s %s\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : gettext ("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, "",
+ elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ }
else
printf (" %#0*" PRIx64 " %-20s <%s %ld>\n",
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
@@ -2045,18 +2060,34 @@ handle_relocs_rela (Ebl *ebl, GElf_Ehdr *ehdr, Elf_Scn *scn, GElf_Shdr *shdr)
}
if (is_statically_linked > 0 && shdr->sh_link == 0)
- printf ("\
- %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
- class == ELFCLASS32 ? 10 : 18, rel->r_offset,
- ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
- /* Avoid the leading R_ which isn't carrying any
- information. */
- ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
- buf, sizeof (buf)) + 2
- : gettext ("<INVALID RELOC>"),
- class == ELFCLASS32 ? 10 : 18, "",
- rel->r_addend,
- elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ {
+ if (unlikely (destshdr == NULL))
+ printf (" %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " <%s %ld>\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : gettext ("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, "",
+ rel->r_addend,
+ gettext ("INVALID SECTION"),
+ (long int) (sym->st_shndx == SHN_XINDEX
+ ? xndx : sym->st_shndx));
+ else
+ printf (" %#0*" PRIx64 " %-15s %*s %#6" PRIx64 " %s\n",
+ class == ELFCLASS32 ? 10 : 18, rel->r_offset,
+ ebl_reloc_type_check (ebl, GELF_R_TYPE (rel->r_info))
+ /* Avoid the leading R_ which isn't carrying any
+ information. */
+ ? ebl_reloc_type_name (ebl, GELF_R_TYPE (rel->r_info),
+ buf, sizeof (buf)) + 2
+ : gettext ("<INVALID RELOC>"),
+ class == ELFCLASS32 ? 10 : 18, "",
+ rel->r_addend,
+ elf_strptr (ebl->elf, shstrndx, destshdr->sh_name));
+ }
else
printf (" %#0*" PRIx64 " %-15s <%s %ld>\n",
class == ELFCLASS32 ? 10 : 18, rel->r_offset,
--
1.9.3
9 years, 4 months
[PATCH] Add configure --disable-textrelcheck option to enable CC=afl-fuzz on 32bit.
by Mark Wielaard
Using american fuzzy lop has found a lot of issues. It would be nice to
make using it a bit easier. Our build files make sure that no shared
library uses text relocations, but afl-gcc will insert some on i686.
http://www.akkadia.org/drepper/textrelocs.html
Now CC=afl-gcc ./configure --disable-textrelcheck will allow them so
that afl can instrument the libraries.
Don't try to use or install them except with afl-fuzz. When selinux is
enabled it might prevent loading the libraries with DT_TEXTREL set.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
ChangeLog | 4 ++++
config/ChangeLog | 5 +++++
config/eu.am | 8 +++++++-
configure.ac | 5 +++++
libasm/ChangeLog | 4 ++++
libasm/Makefile.am | 2 +-
libdw/ChangeLog | 4 ++++
libdw/Makefile.am | 2 +-
libelf/ChangeLog | 4 ++++
libelf/Makefile.am | 2 +-
10 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 0947608..8eeaa08 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-11-27 Mark Wielaard <mjw(a)redhat.com>
+
+ * configure.ac: Add --disable-textrelcheck.
+
2014-10-06 Mark Wielaard <mjw(a)redhat.com>
* NEWS: New section 0.161. Add dwarf_peel_type.
diff --git a/config/ChangeLog b/config/ChangeLog
index 9ebf14f..a05f552 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-27 Mark Wielaard <mjw(a)redhat.com>
+
+ * eu.am: Define textrel_msg, textrel_found and textrel_check based
+ on FATAL_TEXTREL.
+
2014-08-25 Mark Wielaard <mjw(a)redhat.com>
* elfutils.spec.in: Update for 0.160.
diff --git a/config/eu.am b/config/eu.am
index c3b00e0..faf8add 100644
--- a/config/eu.am
+++ b/config/eu.am
@@ -52,4 +52,10 @@ endif
CLEANFILES = *.gcno *.gcda
-textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then exit 1; fi
+textrel_msg = echo "WARNING: TEXTREL found in '$@'"
+if FATAL_TEXTREL
+textrel_found = $(textrel_msg); exit 1
+else
+textrel_found = $(textrel_msg)
+endif
+textrel_check = if $(READELF) -d $@ | fgrep -q TEXTREL; then $(textrel_found); fi
diff --git a/configure.ac b/configure.ac
index 76a172d..9bc83c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -212,6 +212,11 @@ AC_CHECK_LIB([stdc++], [__cxa_demangle], [dnl
AC_DEFINE([USE_DEMANGLE], [1], [Defined if demangling is enabled])])
AM_CONDITIONAL(DEMANGLE, test "$ac_cv_lib_stdcpp___cxa_demangle" = yes)
+AC_ARG_ENABLE([textrelcheck],
+AS_HELP_STRING([--disable-textrelcheck],
+ [Disable textrelcheck being a fatal error]))
+AM_CONDITIONAL(FATAL_TEXTREL, [test "x$enable_textrelcheck" != "xno"])
+
dnl The directories with content.
dnl Documentation.
diff --git a/libasm/ChangeLog b/libasm/ChangeLog
index 2613610..034a64d 100644
--- a/libasm/ChangeLog
+++ b/libasm/ChangeLog
@@ -1,3 +1,7 @@
+2014-01127 Mark Wielaard <mjw(a)redhat.com>
+
+ * Makefile.am (libasm.so): Use textrel_check.
+
2014-04-13 Mark Wielaard <mjw(a)redhat.com>
* Makefile.am: Remove !MUDFLAP conditions.
diff --git a/libasm/Makefile.am b/libasm/Makefile.am
index 3d6a2e5..88c2530 100644
--- a/libasm/Makefile.am
+++ b/libasm/Makefile.am
@@ -66,7 +66,7 @@ libasm.so$(EXEEXT): libasm_pic.a libasm.map
-Wl,--version-script,$(srcdir)/libasm.map,--no-undefined \
-Wl,--soname,$@.$(VERSION) \
../libebl/libebl.a ../libelf/libelf.so $(libasm_so_LDLIBS)
- if $(READELF) -d $@ | fgrep -q TEXTREL; then exit 1; fi
+ $(textrel_check)
ln -fs $@ $@.$(VERSION)
install: install-am libasm.so
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index c199707..bab02e5 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,5 +1,9 @@
2014-11-27 Mark Wielaard <mjw(a)redhat.com>
+ * Makefile.am (libdw.so): Use textrel_check.
+
+2014-11-27 Mark Wielaard <mjw(a)redhat.com>
+
* dwarf_getcfi_elf.c (getcfi_gnu_eh_frame): Initialize
search_table_entries and search_table_encoding.
diff --git a/libdw/Makefile.am b/libdw/Makefile.am
index 852d2c8..7a2a25d 100644
--- a/libdw/Makefile.am
+++ b/libdw/Makefile.am
@@ -113,7 +113,7 @@ libdw.so$(EXEEXT): $(srcdir)/libdw.map libdw_pic.a ../libdwelf/libdwelf_pic.a \
-Wl,--version-script,$<,--no-undefined \
-Wl,--whole-archive $(filter-out $<,$^) -Wl,--no-whole-archive\
-ldl $(zip_LIBS)
- if $(READELF) -d $@ | fgrep -q TEXTREL; then exit 1; fi
+ $(textrel_check)
ln -fs $@ $@.$(VERSION)
install: install-am libdw.so
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 68fb0fc..e03ee09 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,7 @@
+2014-11-27 Mark Wielaard <mjw(a)redhat.com>
+
+ * Makefile.am (libelf.so): Use textrel_check.
+
2014-11-23 Mark Wielaard <mjw(a)redhat.com>
* elf_getdata_rawchunk.c (elf_getdata_rawchunk): Change signed
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 493e4ec..6888529 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -103,7 +103,7 @@ libelf.so$(EXEEXT): libelf_pic.a libelf.map
$(LINK) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
-Wl,--version-script,$(srcdir)/libelf.map,--no-undefined \
-Wl,--soname,$@.$(VERSION),-z,defs,-z,relro $(libelf_so_LDLIBS)
- if $(READELF) -d $@ | fgrep -q TEXTREL; then exit 1; fi
+ $(textrel_check)
ln -fs $@ $@.$(VERSION)
install: install-am libelf.so
--
1.9.3
9 years, 4 months
[PATCH] libdw: Initialize variables in getcfi_gnu_eh_frame.
by Mark Wielaard
Some older GCCs are not clever enough to realize that when search_table
is NULL not only are search_table_entries and search_table_encoding not
initialized, they are also not used. Giving "may be used uninitialized"
errors.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdw/ChangeLog | 5 +++++
libdw/dwarf_getcfi_elf.c | 6 +++---
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 37f94df..c199707 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-27 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf_getcfi_elf.c (getcfi_gnu_eh_frame): Initialize
+ search_table_entries and search_table_encoding.
+
2014-11-24 Mark Wielaard <mjw(a)redhat.com>
* dwarf_getsrclines.c (read_srclines): Check line_range is not zero
diff --git a/libdw/dwarf_getcfi_elf.c b/libdw/dwarf_getcfi_elf.c
index a423ef3..61ca60d 100644
--- a/libdw/dwarf_getcfi_elf.c
+++ b/libdw/dwarf_getcfi_elf.c
@@ -1,5 +1,5 @@
/* Get CFI from ELF file's exception-handling info.
- Copyright (C) 2009-2010 Red Hat, Inc.
+ Copyright (C) 2009-2010, 2014 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -140,8 +140,8 @@ getcfi_gnu_eh_frame (Elf *elf, const GElf_Ehdr *ehdr, const GElf_Phdr *phdr)
}
Dwarf_Addr eh_frame_ptr;
- size_t search_table_entries;
- uint8_t search_table_encoding;
+ size_t search_table_entries = 0;
+ uint8_t search_table_encoding = 0;
const uint8_t *search_table = parse_eh_frame_hdr (data->d_buf, phdr->p_filesz,
phdr->p_vaddr, ehdr,
&eh_frame_ptr,
--
1.9.3
9 years, 4 months
[PATCH] tests: vdsosyms call dwfl_linux_proc_attach.
by Mark Wielaard
Older kernels won't let us get at the vdso otherwise.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
tests/ChangeLog | 4 ++++
tests/vdsosyms.c | 7 +++++++
2 files changed, 11 insertions(+)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 909a61e..87a453d 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,7 @@
+2014-11-27 Mark Wielaard <mjw(a)redhat.com>
+
+ * vdsosyms.c (main): Call dwfl_linux_proc_attach.
+
2014-11-21 Mark Wielaard <mjw(a)redhat.com>
* run-readelf-A.sh: New test.
diff --git a/tests/vdsosyms.c b/tests/vdsosyms.c
index 831caf4..d04f36a 100644
--- a/tests/vdsosyms.c
+++ b/tests/vdsosyms.c
@@ -89,6 +89,13 @@ main (int argc __attribute__ ((unused)), char **argv __attribute__ ((unused)))
else if (result > 0)
error (2, result, "dwfl_linux_proc_report");
+ /* Also explicitly attach for older kernels (cannot read vdso otherwise). */
+ result = dwfl_linux_proc_attach (dwfl, pid, false);
+ if (result < 0)
+ error (2, 0, "dwfl_linux_proc_attach: %s", dwfl_errmsg (-1));
+ else if (result > 0)
+ error (2, result, "dwfl_linux_proc_attach");
+
if (dwfl_report_end (dwfl, NULL, NULL) != 0)
error (2, 0, "dwfl_report_end: %s", dwfl_errmsg (-1));
--
1.9.3
9 years, 4 months
Re: [PATCH] Add --core-pattern option to eu-stack
by Mark Wielaard
On Thu, 2014-10-09 at 23:25 +0200, Jan Kratochvil wrote:
> To backtrace crashed thread from Linux core_pattern handler a special operation
> similar to PTRACE_ATTACH needs to be done. This is implemented as a demo in
> eu-stack's core_pattern function invoked by eu-stack's --core-pattern option.
Cute! And I saw the %i support made it into the mainline kernel:
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?i...
I did have to lookup how to use this though. And I couldn't make it work
without adding an -o option to eu-stack to explicitly redirect output
since it seems you cannot use normal shell redirections
in /proc/sys/kernel/core_pattern. So I had to use something like
--output=/proc/%p/cwd/%i.stack. Where does the stdout of the
core_pattern end up otherwise?
It would probably be good to have a full example usage in the --help
message (and tell people to look at man 5 core).
> The code of core_pattern function has been suggested by Oleg Nesterov.
I was wondering if we could make this a little more generically usable
and call it --wait-exit or something like that. So people could also use
it outside the core_pattern if they just want to get a backtrace for a
known thread when it exits.
> + if (opt_core_pattern == true && show_one_tid == false)
> + argp_error (state,
> + N_("--core-pattern requires -1"));
Why this restriction?
Thanks,
Mark
9 years, 5 months
[COMMITTED] readelf: Cast Dwarf_Word length to ptrdiff_t for comparison.
by Mark Wielaard
My last patch caused a compiler warning/error on some setups. My apologies.
Avoid comparison between signed and unsigned integer expressions warning.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 5 +++++
src/readelf.c | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 0082e65..a6d18b5 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-26 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (print_debug_aranges_section): Cast Dwarf_Word length
+ to ptrdiff_t for comparison.
+
2014-11-24 Mark Wielaard <mjw(a)redhat.com>
* readelf.c (print_debug_line_section): Check line_range is not zero
diff --git a/src/readelf.c b/src/readelf.c
index 00986d1..cd15e4c 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -4693,7 +4693,7 @@ print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
printf (gettext ("\n Length: %6" PRIu64 "\n"),
(uint64_t) length);
- if (unlikely (length > readendp - readp))
+ if (unlikely ((ptrdiff_t) length > readendp - readp))
goto invalid_data;
if (length == 0)
--
1.8.3.1
9 years, 5 months
[PATCH] readelf, libdw: Guard against divide by zero line_range in .debug_line.
by Mark Wielaard
For DW_LNS_const_add_pc and special opcodes don't accept line_range
being zero.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdw/ChangeLog | 5 +++++
libdw/dwarf_getsrclines.c | 6 ++++++
src/ChangeLog | 5 +++++
src/readelf.c | 7 +++++++
4 files changed, 23 insertions(+)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 2241c70..3e77994 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-24 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf_getsrclines.c (read_srclines): Check line_range is not zero
+ before usage.
+
2014-11-23 Mark Wielaard <mjw(a)redhat.com>
* dwarf_attr.c (dwarf_attr): Check __libdw_find_attr return value.
diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
index 15881e8..efdc00f 100644
--- a/libdw/dwarf_getsrclines.c
+++ b/libdw/dwarf_getsrclines.c
@@ -365,6 +365,9 @@ read_srclines (Dwarf *dbg,
/* Is this a special opcode? */
if (likely (opcode >= opcode_base))
{
+ if (line_range == 0)
+ goto invalid_data;
+
/* Yes. Handling this is quite easy since the opcode value
is computed with
@@ -576,6 +579,9 @@ read_srclines (Dwarf *dbg,
if (unlikely (standard_opcode_lengths[opcode] != 0))
goto invalid_data;
+ if (line_range == 0)
+ goto invalid_data;
+
advance_pc ((255 - opcode_base) / line_range);
break;
diff --git a/src/ChangeLog b/src/ChangeLog
index 19509dc..0082e65 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-24 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (print_debug_line_section): Check line_range is not zero
+ before usage.
+
2014-11-23 Mark Wielaard <mjw(a)redhat.com>
* readelf.c (print_debug_aranges_section): Check length to catch
diff --git a/src/readelf.c b/src/readelf.c
index ffc14fd..7573898 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -6507,6 +6507,9 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
/* Is this a special opcode? */
if (likely (opcode >= opcode_base))
{
+ if (line_range == 0)
+ goto invalid_unit;
+
/* Yes. Handling this is quite easy since the opcode value
is computed with
@@ -6682,6 +6685,10 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
case DW_LNS_const_add_pc:
/* Takes no argument. */
+
+ if (line_range == 0)
+ goto invalid_unit;
+
advance_pc ((255 - opcode_base) / line_range);
{
char *a = format_dwarf_addr (dwflmod, 0, address, address);
--
1.9.3
9 years, 5 months