From: Mark Wielaard Date: Sun, 2 Dec 2018 23:03:39 +0000 (+0100) Subject: libebl: Fix reading GNU_PROPERTY_STACK_SIZE reading from 32bit notes. X-Git-Tag: elfutils-0.176~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e8b9832af19e5975fb2a9dbe729eaba0373c781f;p=thirdparty%2Felfutils.git libebl: Fix reading GNU_PROPERTY_STACK_SIZE reading from 32bit notes. When reading a GNU_PROPERTY_STACK_SIZE we need to use the proper data type. GElf_Addr is 64bit always and when reading a 32bit size part of it would not be initialized. Use either Elf32_Addr or Elf64_Addr to read and print the data. Add 32bit and 64bit, little and big endian testcases. Signed-off-by: Mark Wielaard --- diff --git a/libebl/ChangeLog b/libebl/ChangeLog index a2f89562f..0174f331a 100644 --- a/libebl/ChangeLog +++ b/libebl/ChangeLog @@ -1,3 +1,8 @@ +2018-12-02 Mark Wielaard + + * eblobjnte.c (ebl_object_note): For GNU_PROPERTY_STACK_SIZE use + an Elf32_Addr or Elf64_Addr to read and print the size. + 2018-11-15 Mark Wielaard * eblobjnotetypename.c (ebl_object_note_type_name): Don't update diff --git a/libebl/eblobjnote.c b/libebl/eblobjnote.c index 58ac86d7e..c19ea37fc 100644 --- a/libebl/eblobjnote.c +++ b/libebl/eblobjnote.c @@ -360,15 +360,22 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, if (prop.pr_type == GNU_PROPERTY_STACK_SIZE) { printf ("STACK_SIZE "); - if (prop.pr_datasz == 4 || prop.pr_datasz == 8) + union + { + Elf64_Addr a64; + Elf32_Addr a32; + } addr; + if ((elfclass == ELFCLASS32 && prop.pr_datasz == 4) + || (elfclass == ELFCLASS64 && prop.pr_datasz == 8)) { - GElf_Addr addr; in.d_type = ELF_T_ADDR; out.d_type = ELF_T_ADDR; in.d_size = prop.pr_datasz; - out.d_size = sizeof (addr); + out.d_size = prop.pr_datasz; in.d_buf = (void *) desc; - out.d_buf = (void *) &addr; + out.d_buf = (elfclass == ELFCLASS32 + ? (void *) &addr.a32 + : (void *) &addr.a64); if (gelf_xlatetom (ebl->elf, &out, &in, elfident[EI_DATA]) == NULL) @@ -376,7 +383,10 @@ ebl_object_note (Ebl *ebl, uint32_t namesz, const char *name, uint32_t type, printf ("%s\n", elf_errmsg (-1)); return; } - printf ("%#" PRIx64 "\n", addr); + if (elfclass == ELFCLASS32) + printf ("%#" PRIx32 "\n", addr.a32); + else + printf ("%#" PRIx64 "\n", addr.a64); } else printf (" (garbage datasz: %" PRIx32 ")\n", diff --git a/tests/ChangeLog b/tests/ChangeLog index 225a51d5c..1382e40af 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,12 @@ +2018-12-02 Mark Wielaard + + * testfile_gnu_props.32le.o.bz2: New testfile. + * testfile_gnu_props.64le.o.bz2: Likewise. + * testfile_gnu_props.32be.o.bz2: Likewise. + * testfile_gnu_props.64be.o.bz2: Likewise. + * Makefile (EXTRA_DIST): Add new testfiles. + * run-readelf-n.sh: Run tests on new testfiles. + 2018-11-28 Mark Wielaard * backtrace-data.c (main): Improve error message. diff --git a/tests/Makefile.am b/tests/Makefile.am index 3ca0e1c22..bc8c19a63 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -278,6 +278,10 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh run-ar.sh \ run-readelf-types.sh \ run-readelf-n.sh \ testfile-gnu-property-note.bz2 testfile-gnu-property-note.o.bz2 \ + testfile_gnu_props.32le.o.bz2 \ + testfile_gnu_props.64le.o.bz2 \ + testfile_gnu_props.32be.o.bz2 \ + testfile_gnu_props.64be.o.bz2 \ run-allfcts-multi.sh \ test-offset-loop.bz2 test-offset-loop.alt.bz2 \ run-prelink-addr-test.sh \ diff --git a/tests/run-readelf-n.sh b/tests/run-readelf-n.sh index c2db2ce2a..cc7d7f66a 100755 --- a/tests/run-readelf-n.sh +++ b/tests/run-readelf-n.sh @@ -125,3 +125,104 @@ Note section [22] '.note.gnu.property' of 48 bytes at offset 0x40c: X86 0xc0000000 data: 00 00 00 00 X86 0xc0000001 data: 00 00 00 00 EOF + +# +# = gnu_props.S +# +# #define NT_GNU_PROPERTY_TYPE_0 5 +# #define GNU_PROPERTY_STACK_SIZE 1 +# #define GNU_PROPERTY_NO_COPY_ON_PROTECTED 2 + +# /* Normal notes always have alignment and padding of 4 bytes, +# but GNU Property notes use 4 byte words, with 8 byte padding +# for ELFCLASS64. */ +# #if __SIZEOF_PTRDIFF_T__ == 8 +# # define ALIGN 3 +# #elif __SIZEOF_PTRDIFF_T__ == 4 +# # define ALIGN 2 +# #endif +# +# .section ".note.gnu.property", "a" +# .p2align ALIGN +# /* First note. */ +# .long 1f - 0f /* name length. */ +# .long 4f - 2f /* data length. */ +# .long NT_GNU_PROPERTY_TYPE_0 /* note type. */ +# 0: +# .asciz "GNU" /* vendor name. */ +# 1: +# .p2align ALIGN /* Padding. */ +# 2: +# .long GNU_PROPERTY_STACK_SIZE /* pr_type. */ +# .long 4f - 3f /* pr_datasz. */ +# 3: +# .dc.a 0x280000 /* Stack size. */ +# 4: +# .p2align ALIGN +# +# /* Second note. */ +# .long 6f - 5f /* name length. */ +# .long 8f - 7f /* data length. */ +# .long NT_GNU_PROPERTY_TYPE_0 /* note type. */ +# 5: +# .asciz "GNU" /* vendor name. */ +# 6: +# .p2align ALIGN /* Padding. */ +# 7: +# .long GNU_PROPERTY_NO_COPY_ON_PROTECTED /* pr_type. */ +# .long 0 /* pr_datasz. */ +# /* No data. */ +# 8: +# .p2align ALIGN +# +# On x86_64 +# gcc -m64 -c -o testfile_gnu_props_64le.o gnu_props.S +# gcc -m32 -c -o testfile_gnu_props_32le.o gnu_props.S + +testfiles testfile_gnu_props.32le.o testfile_gnu_props.64le.o + +testrun_compare ${abs_top_builddir}/src/readelf -n testfile_gnu_props.32le.o << EOF + +Note section [ 4] '.note.gnu.property' of 52 bytes at offset 0x34: + Owner Data size Type + GNU 12 GNU_PROPERTY_TYPE_0 + STACK_SIZE 0x280000 + GNU 8 GNU_PROPERTY_TYPE_0 + NO_COPY_ON_PROTECTION +EOF + +testrun_compare ${abs_top_builddir}/src/readelf -n testfile_gnu_props.64le.o << EOF + +Note section [ 4] '.note.gnu.property' of 56 bytes at offset 0x40: + Owner Data size Type + GNU 16 GNU_PROPERTY_TYPE_0 + STACK_SIZE 0x280000 + GNU 8 GNU_PROPERTY_TYPE_0 + NO_COPY_ON_PROTECTION +EOF + +# On ppc64 +# gcc -m32 -c -o testfile_gnu_props.32be.o gnu_props.S +# gcc -m64 -c -o testfile_gnu_props.64be.o gnu_props.S + +testfiles testfile_gnu_props.32be.o testfile_gnu_props.64be.o + +testrun_compare ${abs_top_builddir}/src/readelf -n testfile_gnu_props.32be.o << EOF + +Note section [ 4] '.note.gnu.property' of 52 bytes at offset 0x34: + Owner Data size Type + GNU 12 GNU_PROPERTY_TYPE_0 + STACK_SIZE 0x280000 + GNU 8 GNU_PROPERTY_TYPE_0 + NO_COPY_ON_PROTECTION +EOF + +testrun_compare ${abs_top_builddir}/src/readelf -n testfile_gnu_props.64be.o << EOF + +Note section [ 4] '.note.gnu.property' of 56 bytes at offset 0x40: + Owner Data size Type + GNU 16 GNU_PROPERTY_TYPE_0 + STACK_SIZE 0x280000 + GNU 8 GNU_PROPERTY_TYPE_0 + NO_COPY_ON_PROTECTION +EOF diff --git a/tests/testfile_gnu_props.32be.o.bz2 b/tests/testfile_gnu_props.32be.o.bz2 new file mode 100644 index 000000000..60a39fe54 Binary files /dev/null and b/tests/testfile_gnu_props.32be.o.bz2 differ diff --git a/tests/testfile_gnu_props.32le.o.bz2 b/tests/testfile_gnu_props.32le.o.bz2 new file mode 100644 index 000000000..cb5d23c28 Binary files /dev/null and b/tests/testfile_gnu_props.32le.o.bz2 differ diff --git a/tests/testfile_gnu_props.64be.o.bz2 b/tests/testfile_gnu_props.64be.o.bz2 new file mode 100644 index 000000000..784c98bc8 Binary files /dev/null and b/tests/testfile_gnu_props.64be.o.bz2 differ diff --git a/tests/testfile_gnu_props.64le.o.bz2 b/tests/testfile_gnu_props.64le.o.bz2 new file mode 100644 index 000000000..09df3d1ef Binary files /dev/null and b/tests/testfile_gnu_props.64le.o.bz2 differ