]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libelf: Treat elf_memory image as writable users/mark/try-elf_memory
authorMark Wielaard <mark@klomp.org>
Fri, 18 Oct 2024 14:52:49 +0000 (16:52 +0200)
committerMark Wielaard <mark@klomp.org>
Fri, 18 Oct 2024 14:52:49 +0000 (16:52 +0200)
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 <mark@klomp.org>
libelf/elf_memory.c
tests/elfgetzdata.c

index 13d77cb71b39143a8ab007afb310f97d6932edee..1df49d732dd9bd003c490cd9930d1c074c959a05 100644 (file)
@@ -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);
 }
index 0af6c223a06ba4486059ba3e541ef0e80360ebb1..a50275fea1a763351a00c3fd8dfc975d55f5ae54 100644 (file)
@@ -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));