Hi,

So we changed elf_memory so it pretends the in-memory Elf image is
read with ELF_C_READ_MMAP. This helps when calling elf_memory on
read-only memory which still wants to change some things about the Elf
like uncompress some sections (which changes the section header).

With ELF_C_READ_MMAP libelf will make a copy of the section headers,
so any changes aren't written to the memory image (because that would
crash if the underlying memory is read-only).

But that breaks another use case where elf_memory is used on rw memory
and then the section headers are updated using libelf and it is
expected those in-memory section headers reflect the changes.

The problem of course is the elf_memory function doesn't take a "mode"
argument. So we have to guess. And make one or the other usage
unusable.

I think we should assume the memory is read/write and at least header
updates are written back to the memory image. But that when only just
reading the image then nothing is changed and written back to the
image.

This does mean that when explicitly uncompressing sections you have to
make sure the image is writable (because that updates the shdrs).

Is that bad/unreasonable?

Derek, would it make your use case impossible?

John, what kind of Shdr changes are you expecting to get written back
to the memory image. Are there any issues that cannot be worked around
by always using the Shdr copy given back from (g)elf[32|64]_shdr?

The patch I am thinking of is attached.

Cheers,

Mark
diff --git a/libelf/elf_memory.c b/libelf/elf_memory.c
index 13d77cb71b39..1df49d732dd9 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 0af6c223a06b..a50275fea1a7 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));

Reply via email to