[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 09/60] linux-user/elfload: Size corefile before opening
From: |
Richard Henderson |
Subject: |
[PATCH 09/60] linux-user/elfload: Size corefile before opening |
Date: |
Fri, 1 Mar 2024 13:05:28 -1000 |
Verify the size of the corefile vs the rlimit before
opening and creating the core file at all.
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 83 +++++++++++++++++++++++---------------------
1 file changed, 44 insertions(+), 39 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 6f9da721d7..bad01bd2ef 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -4270,6 +4270,16 @@ static int vma_walker(void *priv, target_ulong start,
target_ulong end,
return (0);
}
+static size_t size_note(const char *name, size_t datasz)
+{
+ size_t namesz = strlen(name) + 1;
+
+ namesz = ROUND_UP(namesz, 4);
+ datasz = ROUND_UP(datasz, 4);
+
+ return sizeof(struct elf_note) + namesz + datasz;
+}
+
static void fill_note(struct memelfnote *note, const char *name, int type,
unsigned int sz, void *data)
{
@@ -4428,27 +4438,9 @@ static int dump_write(int fd, const void *ptr, size_t
size)
{
const char *bufp = (const char *)ptr;
ssize_t bytes_written, bytes_left;
- struct rlimit dumpsize;
- off_t pos;
bytes_written = 0;
- getrlimit(RLIMIT_CORE, &dumpsize);
- if ((pos = lseek(fd, 0, SEEK_CUR))==-1) {
- if (errno == ESPIPE) { /* not a seekable stream */
- bytes_left = size;
- } else {
- return pos;
- }
- } else {
- if (dumpsize.rlim_cur <= pos) {
- return -1;
- } else if (dumpsize.rlim_cur == RLIM_INFINITY) {
- bytes_left = size;
- } else {
- size_t limit_left=dumpsize.rlim_cur - pos;
- bytes_left = limit_left >= size ? size : limit_left ;
- }
- }
+ bytes_left = size;
/*
* In normal conditions, single write(2) should do but
@@ -4622,16 +4614,15 @@ static int elf_core_dump(int signr, const CPUArchState
*env)
{
const CPUState *cpu = env_cpu((CPUArchState *)env);
const TaskState *ts = (const TaskState *)cpu->opaque;
- struct vm_area_struct *vma = NULL;
+ struct vm_area_struct *vma;
struct elf_note_info info;
struct elfhdr elf;
struct elf_phdr phdr;
struct rlimit dumpsize;
struct mm_struct mm;
- off_t offset = 0, data_offset = 0;
- int segs = 0;
+ off_t offset, note_offset, data_offset;
+ int segs, cpus, ret;
int fd = -1;
- int ret;
if (prctl(PR_GET_DUMPABLE) == 0) {
return 0;
@@ -4646,10 +4637,36 @@ static int elf_core_dump(int signr, const CPUArchState
*env)
/*
* Walk through target process memory mappings and
- * set up structure containing this information. After
- * this point vma_xxx functions can be used.
+ * set up structure containing this information.
*/
vma_init(&mm);
+ walk_memory_regions(&mm, vma_walker);
+ segs = vma_get_mapping_count(&mm);
+
+ cpus = 0;
+ CPU_FOREACH(cpu) {
+ cpus++;
+ }
+
+ offset = sizeof(struct elfhdr);
+ offset += (segs + 1) * sizeof(struct elf_phdr);
+ note_offset = offset;
+
+ offset += size_note("CORE", ts->info->auxv_len);
+ offset += size_note("CORE", sizeof(struct target_elf_prpsinfo));
+ offset += size_note("CORE", sizeof(struct target_elf_prstatus)) * cpus;
+ offset = ROUND_UP(offset, ELF_EXEC_PAGESIZE);
+ data_offset = offset;
+
+ for (vma = vma_first(&mm); vma != NULL; vma = vma_next(vma)) {
+ offset += vma_dump_size(vma);
+ }
+
+ /* Do not dump if the corefile size exceeds the limit. */
+ if (dumpsize.rlim_cur != RLIM_INFINITY && dumpsize.rlim_cur < offset) {
+ errno = 0;
+ goto out;
+ }
{
g_autofree char *corefile = core_dump_filename(ts);
@@ -4660,9 +4677,6 @@ static int elf_core_dump(int signr, const CPUArchState
*env)
goto out;
}
- walk_memory_regions(&mm, vma_walker);
- segs = vma_get_mapping_count(&mm);
-
/*
* Construct valid coredump ELF header. We also
* add one more segment for notes.
@@ -4674,26 +4688,17 @@ static int elf_core_dump(int signr, const CPUArchState
*env)
/* fill in the in-memory version of notes */
fill_note_info(&info, signr, env);
- offset += sizeof (elf); /* elf header */
- offset += (segs + 1) * sizeof (struct elf_phdr); /* program headers */
-
/* write out notes program header */
- fill_elf_note_phdr(&phdr, info.notes_size, offset);
+ fill_elf_note_phdr(&phdr, info.notes_size, note_offset);
- offset += info.notes_size;
if (dump_write(fd, &phdr, sizeof (phdr)) != 0)
goto out;
- /*
- * ELF specification wants data to start at page boundary so
- * we align it here.
- */
- data_offset = offset = roundup(offset, ELF_EXEC_PAGESIZE);
-
/*
* Write program headers for memory regions mapped in
* the target process.
*/
+ offset = data_offset;
for (vma = vma_first(&mm); vma != NULL; vma = vma_next(vma)) {
(void) memset(&phdr, 0, sizeof (phdr));
--
2.34.1
- [PATCH 02/60] linux-user/elfload: Merge init_note_info and fill_note_info, (continued)
- [PATCH 02/60] linux-user/elfload: Merge init_note_info and fill_note_info, Richard Henderson, 2024/03/01
- [PATCH 03/60] linux-user/elfload: Tidy fill_note_info and struct elf_note_info, Richard Henderson, 2024/03/01
- [PATCH 04/60] linux-user/elfload: Stack allocate struct mm_struct, Richard Henderson, 2024/03/01
- [PATCH 05/60] linux-user/elfload: Latch errno before cleanup in elf_core_dump, Richard Henderson, 2024/03/01
- [PATCH 08/60] linux-user/elfload: Lock cpu list and mmap during elf_core_dump, Richard Henderson, 2024/03/01
- [PATCH 11/60] linux-user/elfload: Write process memory to core file in larger chunks, Richard Henderson, 2024/03/01
- [PATCH 13/60] linux-user/elfload: Rely on walk_memory_regions for vmas, Richard Henderson, 2024/03/01
- [PATCH 15/60] tcg/aarch64: Apple does not align __int128_t in even registers, Richard Henderson, 2024/03/01
- [PATCH 16/60] accel/tcg: Set can_do_io at at start of lookup_tb_ptr helper, Richard Henderson, 2024/03/01
- [PATCH 06/60] linux-user/elfload: Open core file after vma_init, Richard Henderson, 2024/03/01
- [PATCH 09/60] linux-user/elfload: Size corefile before opening,
Richard Henderson <=
- [PATCH 14/60] linux-user/elfload: Unprotect regions before core dump, Richard Henderson, 2024/03/01
- [PATCH 25/60] linux-user: Remove qemu_host_page_size from elf_core_dump, Richard Henderson, 2024/03/01
- [PATCH 19/60] linux-user: Adjust SVr4 NULL page mapping, Richard Henderson, 2024/03/01
- [PATCH 12/60] linux-user/elfload: Simplify vma_dump_size, Richard Henderson, 2024/03/01
- [PATCH 18/60] accel/tcg: Remove qemu_host_page_size from page_protect/page_unprotect, Richard Henderson, 2024/03/01
- [PATCH 26/60] linux-user: Remove qemu_host_page_{size, mask} from mmap.c, Richard Henderson, 2024/03/01
- [PATCH 28/60] linux-user: Remove HOST_PAGE_ALIGN from mmap.c, Richard Henderson, 2024/03/01
- [PATCH 07/60] linux-user/elfload: Truncate core file on open, Richard Henderson, 2024/03/01
- [PATCH 20/60] linux-user: Remove qemu_host_page_{size, mask} in probe_guest_base, Richard Henderson, 2024/03/01
- [PATCH 23/60] linux-user/nios2: Remove qemu_host_page_size from init_guest_commpage, Richard Henderson, 2024/03/01