[COMMITTED] tests: Don't printf a known NULL symname in backtrace-dwarf.c.
GCC9 on 32bit systems might warn about '%s' directive argument is null for symname in backtrace-dwarf.c. Just check whether symname is NULL. This is an identical fix for the same issue as found in backtrace.c, but now in backtrace-dwarf.c Signed-off-by: Mark Wielaard --- tests/ChangeLog | 5 + tests/backtrace-dwarf.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/ChangeLog b/tests/ChangeLog index a4f5dd3..d6dafa4 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,5 +1,10 @@ 2019-04-30 Mark Wielaard + * backtrace-dwarf.c (frame_callback): Explicitly check symname is + NULL. + +2019-04-30 Mark Wielaard + * backtrace.c (frame_callback): Explicitly check symname is NULL. 2019-03-04 Mark Wielaard diff --git a/tests/backtrace-dwarf.c b/tests/backtrace-dwarf.c index dfbf185..f446bc3 100644 --- a/tests/backtrace-dwarf.c +++ b/tests/backtrace-dwarf.c @@ -101,7 +101,7 @@ frame_callback (Dwfl_Frame *state, void *frame_arg) if (mod) symname = dwfl_module_addrname (mod, pc_adjusted); - printf ("%#" PRIx64 "\t%s\n", (uint64_t) pc, symname); + printf ("%#" PRIx64 "\t%s\n", (uint64_t) pc, symname ?: ""); if (symname && (strcmp (symname, "main") == 0 || strcmp (symname, ".main") == 0)) -- 1.8.3.1
[PATCH] libelf: Add n_namesz offset overflow check to gelf_get_note.
During fuzzing of the new xlate_notes testcase I noticed that gelf_get_note didn't check whether the n_namesz of a note was too big. This could lead to offset wrapping around. Causing an infinite loop going over all ELF notes. Fix by adding an overflow check before updating offset. Signed-off-by: Mark Wielaard --- libelf/ChangeLog | 5 + libelf/gelf_getnote.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/libelf/ChangeLog b/libelf/ChangeLog index 5eadaf7..924ff59 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,8 @@ +2019-05-01 Mark Wielaard + + * gelf_getnote.c (gelf_getnote): Check n_namesz doesn't overflow + offset. + 2019-04-30 Mark Wielaard * note_xlate.h (elf_cvt_note): Indicate we only translated the note diff --git a/libelf/gelf_getnote.c b/libelf/gelf_getnote.c index 6d33b35..0f7b9d6 100644 --- a/libelf/gelf_getnote.c +++ b/libelf/gelf_getnote.c @@ -80,11 +80,12 @@ gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr *result, the offset, after adding the namesz, and include padding in descsz to get to the end. */ *name_offset = offset; - offset += n->n_namesz; - if (offset > data->d_size) + if (n->n_namesz > data->d_size + || offset > data->d_size - n->n_namesz) offset = 0; else { + offset += n->n_namesz; /* Include padding. Check below for overflow. */ GElf_Word descsz = (data->d_type == ELF_T_NHDR8 ? NOTE_ALIGN8 (n->n_descsz) -- 1.8.3.1
Re: Dwarf_Op
Hi Mark, yes, I did use dwarf_frame_register(), I believe I mentioned that :). In the case I brought up you're saying it was an elfutils' libdw decision to provide negative number as DW_OP_plus_uconst (unsigned constant)? So there would be no harm to cast it to a signed int?? Do you know if the rules to find the registers will always have only another one register associated to it? Because libdwarf function dwarf_get_fde_info_for_reg3() returns a register_num, which is described as: "Argument register_num should point to a location which will hold the register number associated with the register rule." elfutils only gives us a location description in an array of Dwarf_Op. Does it provide methods to "execute" it so we can get the result of the expressions? Or it delegates it to the consumer? Regards Sasha From: Mark Wielaard Sent: Saturday, April 27, 2019 12:57 PM To: Sasha Da Rocha Pinheiro Cc: elfutils-devel@sourceware.org Subject: Re: Dwarf_Op On Fri, Apr 26, 2019 at 04:48:49PM +, Sasha Da Rocha Pinheiro wrote: > The output from dwarfdump: > > < 5><0x00400918:0x00400974> 0> > > 0x00400918: > 0x0040091c: > 0x00400920: > 0x00400970: > > I'm getting the rules for r30 at PC 0x0040091c. > The value you see -24 from cfa is passed delivered by libdw as: > > (gdb) p/x locations[i] > $19 = {atom = 0x23, number = 0xffe8, number2 = 0x0, offset = 0x0} > > The atom here is DW_OP_plus_uconst. > Previously I have said it was 0xffe8, because the printf with specifier > %x printed that way. But gdb seems to print its full 8 bytes. > I used dwarf_frame_register. > > Even though, the member number is of unsigned int type with signed encoded > values. Am I correct? Yes, a Dwarf_Op struct holds two number elements which are (unsigned 64bit) Dwarf_Words: typedef struct { uint8_t atom; /* Operation */ Dwarf_Word number; /* Operand */ Dwarf_Word number2; /* Possible second operand */ Dwarf_Word offset; /* Offset in location expression */ } Dwarf_Op; I assume you are using dwarf_frame_register () to turn the CFI for a particular register into a location expression (array of Dwarf_Ops). Which in this case would indeed produce DW_OP_call_frame_cfa, DW_OP_plus_uconst (with the constant -24 in number). Unfortunately there is no better/precise way to turn the CFI register rule into a Dwarf Expression Location. But note that if you use the Dwarf_Ops to calculate an Dwarf_Addr, then the 64bit unsigned arithmetic will work out (because the plus of the big unsigned constant will wrap around and turn into a small minus constant). Cheers, Mark
[Bug tools/24509] New: eu-readelf does not know how to dissect DW_AT_discr_list
https://sourceware.org/bugzilla/show_bug.cgi?id=24509 Bug ID: 24509 Summary: eu-readelf does not know how to dissect DW_AT_discr_list Product: elfutils Version: unspecified Status: NEW Severity: normal Priority: P2 Component: tools Assignee: unassigned at sourceware dot org Reporter: tromey at sourceware dot org CC: elfutils-devel at sourceware dot org Target Milestone: --- Consider the Ada test case in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83935#c2. Compiling to a .o and then using eu-readelf will yield something like: ... [6b]variant abbrev: 5 discr_list (block1) 7 byte block: 01 01 ff ff ff ff 07 discr_list has a specified structure, and it would be nice if eu-readelf could dump it more verbosely. -- You are receiving this mail because: You are on the CC list for the bug.
[Bug tools/24509] eu-readelf does not know how to dissect DW_AT_discr_list
https://sourceware.org/bugzilla/show_bug.cgi?id=24509 Mark Wielaard changed: What|Removed |Added CC||mark at klomp dot org --- Comment #1 from Mark Wielaard --- Created attachment 11760 --> https://sourceware.org/bugzilla/attachment.cgi?id=11760&action=edit quick DW_AT_discr_list prototype Here is a quick hack to show something more intelligent. It doesn't yet handle signed values. Could you provide a few different examples that we could use as testcases? -- You are receiving this mail because: You are on the CC list for the bug.
Re: Dwarf_Op
On Wed, May 01, 2019 at 05:08:15PM +, Sasha Da Rocha Pinheiro wrote: > yes, I did use dwarf_frame_register(), I believe I mentioned that :). Sorry, I missed that. > In the case I brought up you're saying it was an elfutils' libdw > decision to provide negative number as DW_OP_plus_uconst (unsigned > constant)? So there would be no harm to cast it to a signed int?? Yes, since I don't believe there is a better representation. There is no DW_OP_plus_sconst for example. > Do you know if the rules to find the registers will always have only > another one register associated to it? Because libdwarf function > dwarf_get_fde_info_for_reg3() returns a register_num, which is > described as: "Argument register_num should point to a location > which will hold the register number associated with the register > rule." I am not familiar with libdwarf, so don't know how to answer this question > elfutils only gives us a location description in an array of > Dwarf_Op. Does it provide methods to "execute" it so we can get the > result of the expressions? Or it delegates it to the consumer? It doesn't have a generic location description "executor". It really should have. But to make it generic it needs a lot of context. libdwfl does contain a partial operator interpreter for unwinding. See expr_eval in libdwfl/frame_unwind.c. To turn that into something more generic we would need some way to provide it with things like memory accessors and register values. libdwfl provides some of that through dwfl_attach_state. Cheers, Mark