[PATCH] readelf: Don't print more augmentation characters than there are.
by Mark Wielaard
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 5 +++++
src/readelf.c | 7 ++++---
2 files changed, 9 insertions(+), 3 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 456e5a4..0ae7e46 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2014-12-11 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (print_debug_frame_section): Check number of augmentation
+ chars to print.
+
2014-12-09 Mark Wielaard <mjw(a)redhat.com>
* readelf.c (handle_file_note): Check count fits data section and
diff --git a/src/readelf.c b/src/readelf.c
index c6d10f7..31a0e0a 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -5490,7 +5490,7 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
unsigned int augmentationlen;
get_uleb128 (augmentationlen, readp);
- if (augmentationlen > (size_t) (dataend - readp))
+ if (augmentationlen > (size_t) (cieend - readp))
{
error (0, 0, gettext ("invalid augmentation length"));
readp = cieend;
@@ -5499,7 +5499,7 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
const char *hdr = "Augmentation data:";
const char *cp = augmentation + 1;
- while (*cp != '\0')
+ while (*cp != '\0' && cp < augmentation + augmentationlen + 1)
{
printf (" %-26s%#x ", hdr, *readp);
hdr = "";
@@ -5655,7 +5655,8 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
const char *hdr = "Augmentation data:";
const char *cp = cie->augmentation + 1;
unsigned int u = 0;
- while (*cp != '\0')
+ while (*cp != '\0'
+ && cp < cie->augmentation + augmentationlen + 1)
{
if (*cp == 'L')
{
--
1.8.3.1
9 years, 4 months
[PATCH] libelf: Correct ELF64 section offset check in file_read_elf.
by Mark Wielaard
The ELF64 case didn't check for overflow and accidentially used the 32bit
Shdr size.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 4 ++++
libelf/elf_begin.c | 4 ++--
2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index e4c5849..cf168e7 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,5 +1,9 @@
2014-12-11 Mark Wielaard <mjw(a)redhat.com>
+ * elf_begin.c (file_read_elf): Correct ELF64 section offset check.
+
+2014-12-11 Mark Wielaard <mjw(a)redhat.com>
+
* elf_begin.c (read_long_names): Check for offset overflow.
(__libelf_next_arhdr_wrlock): Likewise. Sanity check the ar_size.
Don't allow it to go beyond end of file.
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index 99a9c0a..7fb5fa5 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -412,8 +412,8 @@ file_read_elf (int fildes, void *map_address, unsigned char *e_ident,
elf->state.elf64.ehdr = ehdr;
if (unlikely (ehdr->e_shoff >= maxsize)
- || unlikely (ehdr->e_shoff
- + scncnt * sizeof (Elf32_Shdr) > maxsize))
+ || unlikely (maxsize - ehdr->e_shoff
+ < scncnt * sizeof (Elf64_Shdr)))
goto free_and_out;
elf->state.elf64.shdr
= (Elf64_Shdr *) ((char *) ehdr + ehdr->e_shoff);
--
1.8.3.1
9 years, 4 months
[PATCH] libelf: Add some ar header sanity checking.
by Mark Wielaard
Don't allow entries or size to overflow the parent file size.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 6 ++++++
libelf/elf_begin.c | 15 ++++++++++++---
2 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 4860530..e4c5849 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,9 @@
+2014-12-11 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf_begin.c (read_long_names): Check for offset overflow.
+ (__libelf_next_arhdr_wrlock): Likewise. Sanity check the ar_size.
+ Don't allow it to go beyond end of file.
+
2014-12-09 Mark Wielaard <mjw(a)redhat.com>
* elf_getarsym.c (elf_getarsym): Make sure n * w doesn't overflow.
diff --git a/libelf/elf_begin.c b/libelf/elf_begin.c
index d135dea..99a9c0a 100644
--- a/libelf/elf_begin.c
+++ b/libelf/elf_begin.c
@@ -673,7 +673,8 @@ read_long_names (Elf *elf)
{
if (elf->map_address != NULL)
{
- if (offset + sizeof (struct ar_hdr) > elf->maximum_size)
+ if ((size_t) offset > elf->maximum_size
+ || elf->maximum_size - offset < sizeof (struct ar_hdr))
return NULL;
/* The data is mapped. */
@@ -767,8 +768,10 @@ __libelf_next_arhdr_wrlock (elf)
if (elf->map_address != NULL)
{
/* See whether this entry is in the file. */
- if (unlikely (elf->state.ar.offset + sizeof (struct ar_hdr)
- > elf->start_offset + elf->maximum_size))
+ if (unlikely ((size_t) elf->state.ar.offset
+ > elf->start_offset + elf->maximum_size
+ || (elf->start_offset + elf->maximum_size
+ - elf->state.ar.offset) < sizeof (struct ar_hdr)))
{
/* This record is not anymore in the file. */
__libelf_seterrno (ELF_E_RANGE);
@@ -912,6 +915,12 @@ __libelf_next_arhdr_wrlock (elf)
INT_FIELD (ar_mode);
INT_FIELD (ar_size);
+ /* Truncated file? */
+ size_t maxsize;
+ maxsize = elf->maximum_size - elf->state.ar.offset - sizeof (struct ar_hdr);
+ if ((size_t) elf_ar_hdr->ar_size > maxsize)
+ elf_ar_hdr->ar_size = maxsize;
+
return 0;
}
--
1.8.3.1
9 years, 4 months
[PATCH] libdw: Fix __libdw_form_val_len endp pointer.
by Mark Wielaard
While rebasing my work on top of Josh attrabbrev reading speedups
I noticed a typo/thinko in my form_val_len bound checking patch.
We should check against the die->cu->endp, not the abbrev endp.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdw/ChangeLog | 6 ++++++
libdw/dwarf_child.c | 2 +-
libdw/dwarf_getattrs.c | 2 +-
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 69592a7..8b00970 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,9 @@
+2014-12-11 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf_child.c (__libdw_find_attr): Call __libdw_form_val_len with
+ die->cu->endp, not the abbrev endp.
+ * dwarf_getattrs.c (dwarf_getattrs): Likewise.
+
2014-12-10 Josh Stone <jistone(a)redhat.com>
* libdwP.h (Dwarf_CU): Add startp and endp boundaries.
diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c
index 2a5d379..46d010d 100644
--- a/libdw/dwarf_child.c
+++ b/libdw/dwarf_child.c
@@ -95,7 +95,7 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name,
if (attr_form != 0)
{
size_t len = __libdw_form_val_len (dbg, die->cu, attr_form, readp,
- endp);
+ die->cu->endp);
if (unlikely (len == (size_t) -1l))
{
diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c
index 9ea70fc..f6453c7 100644
--- a/libdw/dwarf_getattrs.c
+++ b/libdw/dwarf_getattrs.c
@@ -107,7 +107,7 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *),
if (attr.form != 0)
{
size_t len = __libdw_form_val_len (dbg, die->cu, attr.form,
- die_addr, endp);
+ die_addr, die->cu->endp);
if (unlikely (len == (size_t) -1l))
/* Something wrong with the file. */
--
2.1.0
9 years, 4 months
[PATCH] tests: Add an explicit -fasynchronous-unwind-tables for deleted-lib.so.
by Mark Wielaard
Some systems don't add a PT_GNU_EH_FRAME segment by default, but the
deleted test depends on it so that it can get at the .eh_frame_hdr table
through the phdrs from the remote memory ELF image. Request one explicitly
with -fasynchronous-unwind-tables.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
tests/ChangeLog | 5 +++++
tests/Makefile.am | 2 +-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 9d229c9..51513b8 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2014-12-12 Mark Wielaard <mjw(a)redhat.com>
+
+ * Makefile.am (deleted_lib_so_CFLAGS): Add
+ -fasynchronous-unwind-tables.
+
2014-12-10 Josh Stone <jistone(a)redhat.com>
* run-addr2line-i-test.sh: Test 0x5f0 to make sure linkage_name is
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 5b38113..ad9baf4 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -414,7 +414,7 @@ debugaltlink_LDADD = $(libdw) $(libelf)
buildid_LDADD = $(libdw) $(libelf)
deleted_LDADD = ./deleted-lib.so
deleted_lib_so_LDFLAGS = -shared -rdynamic
-deleted_lib_so_CFLAGS = -fPIC
+deleted_lib_so_CFLAGS = -fPIC -fasynchronous-unwind-tables
aggregate_size_LDADD = $(libdw) $(libelf)
vdsosyms_LDADD = $(libdw) $(libelf)
--
2.1.0
9 years, 4 months
[PATCH] libelf: Make sure n * w doesn't overflow in elf_getarsym.
by Mark Wielaard
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libelf/ChangeLog | 4 ++++
libelf/elf_getarsym.c | 2 +-
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index e03ee09..4860530 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -1,3 +1,7 @@
+2014-12-09 Mark Wielaard <mjw(a)redhat.com>
+
+ * elf_getarsym.c (elf_getarsym): Make sure n * w doesn't overflow.
+
2014-11-27 Mark Wielaard <mjw(a)redhat.com>
* Makefile.am (libelf.so): Use textrel_check.
diff --git a/libelf/elf_getarsym.c b/libelf/elf_getarsym.c
index 7325190..ba88aa0 100644
--- a/libelf/elf_getarsym.c
+++ b/libelf/elf_getarsym.c
@@ -186,7 +186,7 @@ elf_getarsym (elf, ptr)
#if SIZE_MAX <= 4294967295U
|| n >= SIZE_MAX / sizeof (Elf_Arsym)
#endif
- || n * w > index_size)
+ || n > index_size / w)
{
/* This index table cannot be right since it does not fit into
the file. */
--
1.8.3.1
9 years, 4 months
[PATCH] readelf: Check count fits and doesn't overflow fptr in handle_file_note.
by Mark Wielaard
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 5 +++++
src/readelf.c | 8 ++++++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 4771dc9..456e5a4 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2014-12-09 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (handle_file_note): Check count fits data section and
+ doesn't overflow fptr.
+
2014-12-08 Mark Wielaard <mjw(a)redhat.com>
* readelf.c (print_debug_exception_table): Report invalid data if
diff --git a/src/readelf.c b/src/readelf.c
index 1db54c6..c6d10f7 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -9017,9 +9017,13 @@ handle_file_note (Elf *core, GElf_Word descsz, GElf_Off desc_pos)
return;
}
+ size_t addrsize = gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
+ uint64_t maxcount = (size_t) (end - ptr) / (3 * addrsize);
+ if (count > maxcount)
+ goto fail;
+
/* Where file names are stored. */
- unsigned char const *const fstart
- = ptr + 3 * count * gelf_fsize (core, ELF_T_ADDR, 1, EV_CURRENT);
+ unsigned char const *const fstart = ptr + 3 * count * addrsize;
char const *fptr = (char *) fstart;
printf (" %" PRId64 " files:\n", count);
--
1.8.3.1
9 years, 4 months
[PATCH 0/3] libdw: Tweaks for optimization and clarity
by Josh Stone
While looking at performance for Mark's form-len patch, I found a few areas
that I felt could be cleaned up a bit.
1. die->abbrev initialization was duplicated in a few places.
2. dwarf_hasattr needn't look at the die at all, just abbrev.
3. CU start/end boundaries don't need to be computed from section data
every time -- just remember them in Dwarf_CU.
These patches get me back down to about 71s for "varlocs -k >/dev/null". :)
---
libdw/ChangeLog | 19 +++++++++++++++++++
libdw/dwarf_child.c | 47 ++++++++++++++++++-----------------------------
libdw/dwarf_cuoffset.c | 4 ++--
libdw/dwarf_dieoffset.c | 4 ++--
libdw/dwarf_getattrs.c | 21 ++++++++-------------
libdw/dwarf_hasattr.c | 42 ++++++++++++++++++++++++++++++++++++++----
libdw/dwarf_haschildren.c | 20 ++++----------------
libdw/dwarf_siblingof.c | 6 ++----
libdw/dwarf_tag.c | 20 +++++---------------
libdw/libdwP.h | 28 +++++++++++++++++++++++++++-
libdw/libdw_findcu.c | 6 +++++-
11 files changed, 130 insertions(+), 87 deletions(-)
9 years, 4 months
[PATCH 0/2] Tweak addr2line function names
by Josh Stone
As previously discussed, these patches fix the function names for addr2line.
For addr2line -i, it now walks as many scopes as necessary to find the
containing function, instead of assuming it's the next scope. Also, addr2line
now prefers linkage_name over the plain die name in all cases.
I haven't addressed the srcline sorting yet, but I intend to.
I had also mentioned some redundancy in the way -f prints inlines, compared to
similar info from -i, but I didn't realize that -S and -x are also involved
here. I've decided to leave that alone for now.
---
src/ChangeLog | 8 +++++++
src/addr2line.c | 55 +++++++++++++++++++++++++++----------------
tests/ChangeLog | 5 ++++
tests/run-addr2line-i-test.sh | 4 +++-
4 files changed, 51 insertions(+), 21 deletions(-)
9 years, 4 months
[PATCH] readelf: maximum operations per instruction cannot be zero in .debug_line.
by Mark Wielaard
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 5 +++++
src/readelf.c | 8 ++++++++
2 files changed, 13 insertions(+)
diff --git a/src/ChangeLog b/src/ChangeLog
index ccbd6e8..1c3cf2f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,10 @@
2014-12-07 Mark Wielaard <mjw(a)redhat.com>
+ * readelf.c (print_debug_line_section): max_ops_per_instr cannot
+ be zero.
+
+2014-12-07 Mark Wielaard <mjw(a)redhat.com>
+
* readelf.c (print_ops): Handle zero ref_size for DW_OP_call_ref
and DW_OP_GNU_implicit_pointer.
diff --git a/src/readelf.c b/src/readelf.c
index 881bb45..fa9ede1 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -6506,6 +6506,14 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
op_index = (op_index + op_advance) % max_ops_per_instr;
}
+ if (max_ops_per_instr == 0)
+ {
+ error (0, 0,
+ gettext ("invalid maximum operations per instruction is zero"));
+ linep = lineendp;
+ continue;
+ }
+
while (linep < lineendp)
{
size_t offset = linep - (const unsigned char *) data->d_buf;
--
1.9.3
9 years, 4 months