From 81981fdfd8f776508579da60d29e068359c61e6a Mon Sep 17 00:00:00 2001 From: Mark Wielaard Date: Fri, 18 Oct 2024 16:52:49 +0200 Subject: [PATCH] libelf: Treat elf_memory image as writable There are use cases where the Elf image created by elf_memory is manipulated, through the libelf interfaces, in place. This doesn't work anymore since we changed elf_memory to assume the memory is read-only in elfutils 0.191. commit cc44ac674 ('libelf: Treat elf_memory as if using ELF_C_READ_MMAP'). The reason for that change was that if elf_memory was given a read-only memory image then decompressing a section with elf_compress would crash. Since it directly writes the updated Shdr size. If you do want to use elf_compress on an Elf created by elf_memory you have make sure the memory is writable. You can do this for example by using mmap PROTE_WRITE and MAP_PRIVATE. * libelf/elf_memory.c (elf_memory): Call __libelf_read_mmaped_file with ELF_C_READ_MMAP_PRIVATE. * tests/elfgetzdata.c (main): Use mmap PROT_WRITE and MAP_PRIVATE. Signed-off-by: Mark Wielaard --- libelf/elf_memory.c | 3 ++- tests/elfgetzdata.c | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c index 13d77cb71..1df49d732 100644 --- a/libelf/elf_memory.c +++ b/libelf/elf_memory.c @@ -46,5 +46,6 @@ elf_memory (char *image, size_t size) return NULL; } - return __libelf_read_mmaped_file (-1, image, 0, size, ELF_C_READ_MMAP, NULL); + return __libelf_read_mmaped_file (-1, image, 0, size, + ELF_C_READ_MMAP_PRIVATE, NULL); } diff --git a/tests/elfgetzdata.c b/tests/elfgetzdata.c index 0af6c223a..a50275fea 100644 --- a/tests/elfgetzdata.c +++ b/tests/elfgetzdata.c @@ -69,7 +69,8 @@ main (int argc, char *argv[]) else { assert (do_mem); - // We mmap the memory ourselves, explicitly PROT_READ only + // We mmap the memory ourselves, explicitly PROT_READ | PROT_WRITE + // elf_memory needs writable memory when using elf_compress. struct stat st; if (fstat (fd, &st) != 0) { @@ -79,7 +80,8 @@ main (int argc, char *argv[]) continue; } map_size = st.st_size; - map_address = mmap (NULL, map_size, PROT_READ, MAP_PRIVATE, fd, 0); + map_address = mmap (NULL, map_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE, fd, 0); if (map_address == MAP_FAILED) { printf ("%s cannot mmap %s\n", argv[cnt], strerror (errno)); -- 2.47.2