Blame SOURCES/0003-gcore-fix-memory-allocation-failure-during-processin.patch

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