|
|
94e75a |
From 4cb65a0d9168778d120920418b968d05da10989f Mon Sep 17 00:00:00 2001
|
|
|
94e75a |
From: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
|
|
94e75a |
Date: Fri, 25 Feb 2022 04:59:48 -0500
|
|
|
94e75a |
Subject: [PATCH 3/3] gcore: fix memory allocation failure during processing
|
|
|
94e75a |
NT_AUXV note
|
|
|
94e75a |
|
|
|
94e75a |
For crash dumps generated using kernel-4.18.0-365.el8 or later on
|
|
|
94e75a |
CentOS stream 8, crash gcore command fails as follows:
|
|
|
94e75a |
|
|
|
94e75a |
crash> gcore -v 7 -f 128 10604
|
|
|
94e75a |
gcore: Opening file core.10604.test-dumpfilter ...
|
|
|
94e75a |
gcore: done.
|
|
|
94e75a |
gcore: Writing ELF header ...
|
|
|
94e75a |
gcore: done.
|
|
|
94e75a |
gcore: Retrieving and writing note information ...
|
|
|
94e75a |
gcore: zero-size memory allocation! (called from 7fd558ce1e05)
|
|
|
94e75a |
Failed.
|
|
|
94e75a |
|
|
|
94e75a |
This memory allocation failure occurs in fill_auxv_note() that creates
|
|
|
94e75a |
NT_AUXV note due to saved_auxv entries of size and offset tables are
|
|
|
94e75a |
somehow 0.
|
|
|
94e75a |
|
|
|
94e75a |
This is because during the merge of the upstream kernel commit
|
|
|
94e75a |
1c33bb0507508af24fd754dd7123bd8e997fab2f (x86/elf: Support a new ELF
|
|
|
94e75a |
aux vector AT_MINSIGSTKSZ), location of saved_auxv of struct mm_struct
|
|
|
94e75a |
has been moved as workaround in order to avoid kABI breakage.
|
|
|
94e75a |
|
|
|
94e75a |
Fix this by using RHEL-specific location for saved_auxv if there is
|
|
|
94e75a |
member rh_reserved_saved_auxv in struct mm_struct.
|
|
|
94e75a |
|
|
|
94e75a |
Signed-off-by: HATAYAMA Daisuke <d.hatayama@fujitsu.com>
|
|
|
94e75a |
---
|
|
|
94e75a |
src/libgcore/gcore_coredump.c | 54 +++++++++++++++++++++++++++++------
|
|
|
94e75a |
1 file changed, 46 insertions(+), 8 deletions(-)
|
|
|
94e75a |
|
|
|
94e75a |
diff --git a/src/libgcore/gcore_coredump.c b/src/libgcore/gcore_coredump.c
|
|
|
94e75a |
index 6f57b21b62b6..c14cc116e951 100644
|
|
|
94e75a |
--- a/src/libgcore/gcore_coredump.c
|
|
|
94e75a |
+++ b/src/libgcore/gcore_coredump.c
|
|
|
94e75a |
@@ -18,6 +18,10 @@
|
|
|
94e75a |
|
|
|
94e75a |
static struct elf_note_info *elf_note_info_init(void);
|
|
|
94e75a |
|
|
|
94e75a |
+static void get_auxv_size_addr(struct task_context *tc,
|
|
|
94e75a |
+ size_t *size,
|
|
|
94e75a |
+ ulong *addr);
|
|
|
94e75a |
+
|
|
|
94e75a |
static void fill_prstatus_note(struct elf_note_info *info,
|
|
|
94e75a |
struct task_context *tc,
|
|
|
94e75a |
struct memelfnote *memnote);
|
|
|
94e75a |
@@ -923,18 +927,49 @@ compat_fill_prstatus_note(struct elf_note_info *info,
|
|
|
94e75a |
|
|
|
94e75a |
#endif /* GCORE_ARCH_COMPAT */
|
|
|
94e75a |
|
|
|
94e75a |
+static void get_auxv_size_addr(struct task_context *tc,
|
|
|
94e75a |
+ size_t *psize,
|
|
|
94e75a |
+ ulong *paddr)
|
|
|
94e75a |
+{
|
|
|
94e75a |
+ size_t size;
|
|
|
94e75a |
+ ulong addr;
|
|
|
94e75a |
+
|
|
|
94e75a |
+ if (MEMBER_EXISTS("mm_struct", "rh_reserved_saved_auxv")) {
|
|
|
94e75a |
+ ulong mm_rh;
|
|
|
94e75a |
+
|
|
|
94e75a |
+ size = MEMBER_SIZE("mm_struct_rh", "saved_auxv");
|
|
|
94e75a |
+ readmem(task_mm(tc->task, FALSE) + MEMBER_OFFSET("mm_struct", "mm_rh"),
|
|
|
94e75a |
+ KVADDR,
|
|
|
94e75a |
+ &mm_rh,
|
|
|
94e75a |
+ sizeof(mm_rh),
|
|
|
94e75a |
+ "mm_struct mm_rh",
|
|
|
94e75a |
+ gcore_verbose_error_handle());
|
|
|
94e75a |
+ addr = mm_rh + MEMBER_OFFSET("mm_struct_rh", "saved_auxv");
|
|
|
94e75a |
+ } else {
|
|
|
94e75a |
+ size = MEMBER_SIZE("mm_struct", "saved_auxv");
|
|
|
94e75a |
+ addr = task_mm(tc->task, FALSE) +
|
|
|
94e75a |
+ MEMBER_OFFSET("mm_struct", "saved_auxv");
|
|
|
94e75a |
+ }
|
|
|
94e75a |
+
|
|
|
94e75a |
+ *psize = size;
|
|
|
94e75a |
+ *paddr = addr;
|
|
|
94e75a |
+}
|
|
|
94e75a |
+
|
|
|
94e75a |
static void
|
|
|
94e75a |
fill_auxv_note(struct elf_note_info *info, struct task_context *tc,
|
|
|
94e75a |
struct memelfnote *memnote)
|
|
|
94e75a |
{
|
|
|
94e75a |
ulong *auxv;
|
|
|
94e75a |
+ ulong addr;
|
|
|
94e75a |
+ size_t size;
|
|
|
94e75a |
int i;
|
|
|
94e75a |
|
|
|
94e75a |
- auxv = (ulong *)GETBUF(MEMBER_SIZE("mm_struct", "saved_auxv"));
|
|
|
94e75a |
+ get_auxv_size_addr(tc, &size, &addr);
|
|
|
94e75a |
|
|
|
94e75a |
- readmem(task_mm(tc->task, FALSE) +
|
|
|
94e75a |
- MEMBER_OFFSET("mm_struct", "saved_auxv"), KVADDR, auxv,
|
|
|
94e75a |
- MEMBER_SIZE("mm_struct", "saved_auxv"), "fill_auxv_note",
|
|
|
94e75a |
+ auxv = (ulong *)GETBUF(size);
|
|
|
94e75a |
+
|
|
|
94e75a |
+ readmem(addr, KVADDR, auxv,
|
|
|
94e75a |
+ size, "fill_auxv_note",
|
|
|
94e75a |
gcore_verbose_error_handle());
|
|
|
94e75a |
|
|
|
94e75a |
i = 0;
|
|
|
94e75a |
@@ -954,13 +989,16 @@ compat_fill_auxv_note(struct elf_note_info *info,
|
|
|
94e75a |
struct memelfnote *memnote)
|
|
|
94e75a |
{
|
|
|
94e75a |
uint32_t *auxv;
|
|
|
94e75a |
+ ulong addr;
|
|
|
94e75a |
+ size_t size;
|
|
|
94e75a |
int i;
|
|
|
94e75a |
|
|
|
94e75a |
- auxv = (uint32_t *)GETBUF(MEMBER_SIZE("mm_struct", "saved_auxv"));
|
|
|
94e75a |
+ get_auxv_size_addr(tc, &size, &addr);
|
|
|
94e75a |
+
|
|
|
94e75a |
+ auxv = (uint32_t *)GETBUF(size);
|
|
|
94e75a |
|
|
|
94e75a |
- readmem(task_mm(tc->task, FALSE) +
|
|
|
94e75a |
- MEMBER_OFFSET("mm_struct", "saved_auxv"), KVADDR, auxv,
|
|
|
94e75a |
- MEMBER_SIZE("mm_struct", "saved_auxv"), "fill_auxv_note32",
|
|
|
94e75a |
+ readmem(addr, KVADDR, auxv,
|
|
|
94e75a |
+ size, "fill_auxv_note32",
|
|
|
94e75a |
gcore_verbose_error_handle());
|
|
|
94e75a |
|
|
|
94e75a |
i = 0;
|
|
|
94e75a |
--
|
|
|
94e75a |
2.30.2
|
|
|
94e75a |
|