[Bug libdw/26177] New: eu-unstrip -n -k fail on kernels 4.14-4.19

vt at altlinux dot org sourceware-bugzilla@sourceware.org
Fri Jun 26 21:37:05 GMT 2020


            Bug ID: 26177
           Summary: eu-unstrip -n -k fail on kernels 4.14-4.19
           Product: elfutils
           Version: unspecified
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: libdw
          Assignee: unassigned at sourceware dot org
          Reporter: vt at altlinux dot org
                CC: elfutils-devel at sourceware dot org
  Target Milestone: ---

Error behavior:

 4.19.127-rt-alt2.rt54:~# eu-unstrip -n -k
 eu-unstrip: cannot load kernel symbols: Exec format error

Bug investigation:

In kernels from 4.14 up to 4.19 (which are still maintained stable versions)
there is __entry_SYSCALL_64_trampoline symbol. In /proc/kallsyms is is located
just before module symbols and its address is in much lower address space than
rest of the kernel. Example

 4.19.127-rt54:~# grep -2 -m2 -i ' [rt] ' /proc/kallsyms
 000000000009af40 A rt_uncached_list
 000000000009af80 A __per_cpu_end
 ffffffff81000000 T startup_64 <- this will be kernel 'start' address
 ffffffff81000000 T _stext
 ffffffff81000000 T _text
 ffffffff81000030 T secondary_startup_64

 4.19.127-rt54:~# grep -2 __entry_SYSCALL_64_trampoline /proc/kallsyms
 ffffffff8282c000 B _end
 ffffffff8282c000 B __brk_limit
 fffffe0000006000 t __entry_SYSCALL_64_trampoline
 fffffe0000032000 t __entry_SYSCALL_64_trampoline
 fffffe000005e000 t __entry_SYSCALL_64_trampoline
 fffffe000008a000 t __entry_SYSCALL_64_trampoline
 fffffe00000b6000 t __entry_SYSCALL_64_trampoline
 fffffe00000e2000 t __entry_SYSCALL_64_trampoline
 fffffe000010e000 t __entry_SYSCALL_64_trampoline
 fffffe000013a000 t __entry_SYSCALL_64_trampoline
 fffffe0000166000 t __entry_SYSCALL_64_trampoline
 fffffe0000192000 t __entry_SYSCALL_64_trampoline
 fffffe00001be000 t __entry_SYSCALL_64_trampoline
 fffffe00001ea000 t __entry_SYSCALL_64_trampoline
 fffffe0000216000 t __entry_SYSCALL_64_trampoline
 fffffe0000242000 t __entry_SYSCALL_64_trampoline
 fffffe000026e000 t __entry_SYSCALL_64_trampoline
 fffffe000029a000 t __entry_SYSCALL_64_trampoline
 fffffe00002c6000 t __entry_SYSCALL_64_trampoline
 fffffe00002f2000 t __entry_SYSCALL_64_trampoline
 fffffe000031e000 t __entry_SYSCALL_64_trampoline
 fffffe000034a000 t __entry_SYSCALL_64_trampoline
 fffffe0000376000 t __entry_SYSCALL_64_trampoline
 fffffe00003a2000 t __entry_SYSCALL_64_trampoline
 fffffe00003ce000 t __entry_SYSCALL_64_trampoline
 fffffe00003fa000 t __entry_SYSCALL_64_trampoline
 fffffe0000426000 t __entry_SYSCALL_64_trampoline
 fffffe0000452000 t __entry_SYSCALL_64_trampoline
 fffffe000047e000 t __entry_SYSCALL_64_trampoline
 fffffe00004aa000 t __entry_SYSCALL_64_trampoline
 fffffe00004d6000 t __entry_SYSCALL_64_trampoline
 fffffe0000502000 t __entry_SYSCALL_64_trampoline
 fffffe000052e000 t __entry_SYSCALL_64_trampoline
 fffffe000055a000 t __entry_SYSCALL_64_trampoline
 ffffffffc06ec024 r _note_6      [amd64_edac_mod]
 ffffffffc06ec040 r __ksymtab_amd64_get_dram_hole_info   [amd64_edac_mod]

Root of he problem is in the

It is using read_address() until false is returned, which is returned when
module symmbol is detected (determined by presence of ']' as the last char of
the address line). Last successfuly read address is assumed to be 'end' address
of the kernel space.

In my example ffffffff8282c000 thould be the 'end' address, but, with
__entry_SYSCALL_64_trampoline present the 'end' address is assumed to be
fffffe000055a000. This make intuit_kernel_bounds() return ENOEXEC. Which is
reported by eu-unstrip.

Possible fix:

Just ignore __entry_SYSCALL_64_trampoline in read_address(). Example patch:

diff --git libdwfl/linux-kernel-modules.c libdwfl/linux-kernel-modules.c
index 84a05f28..8c01ce13 100644
--- libdwfl/linux-kernel-modules.c
+++ libdwfl/linux-kernel-modules.c
@@ -502,12 +502,18 @@ struct read_address_state {
   const char *type;

+#define ENTRY_TRAMPOLINE_NAME "__entry_SYSCALL_64_trampoline\n"
 static inline bool
 read_address (struct read_address_state *state, Dwarf_Addr *addr)
   if ((state->n = getline (&state->line, &state->linesz, state->f)) < 1 ||
       state->line[state->n - 2] == ']')
     return false;
+  if (state->n > sizeof(ENTRY_TRAMPOLINE_NAME) &&
+             state->line + state->n - sizeof(ENTRY_TRAMPOLINE_NAME) + 1))
+    return false;
   *addr = strtoull (state->line, &state->p, 16);
   state->p += strspn (state->p, " \t");
   state->type = strsep (&state->p, " \t\n");

After suggested fix is applied:

 4.19.127-rt-alt2.rt54:~/src/elfutils# LD_LIBRARY_PATH=libdw src/unstrip -n -k

You are receiving this mail because:
You are on the CC list for the bug.

More information about the Elfutils-devel mailing list