binfmt: don't use MAP_DENYWRITE when loading shared libraries via uselib()
authorDavid Hildenbrand <david@redhat.com>
Thu, 22 Apr 2021 10:53:00 +0000 (12:53 +0200)
committerDavid Hildenbrand <david@redhat.com>
Fri, 3 Sep 2021 16:42:01 +0000 (18:42 +0200)
uselib() is the legacy systemcall for loading shared libraries.
Nowadays, applications use dlopen() to load shared libraries, completely
implemented in user space via mmap().

For example, glibc uses MAP_COPY to mmap shared libraries. While this
maps to MAP_PRIVATE | MAP_DENYWRITE on Linux, Linux ignores any
MAP_DENYWRITE specification from user space in mmap.

With this change, all remaining in-tree users of MAP_DENYWRITE use it
to map an executable. We will be able to open shared libraries loaded
via uselib() writable, just as we already can via dlopen() from user
space.

This is one step into the direction of removing MAP_DENYWRITE from the
kernel. This can be considered a minor user space visible change.

Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
Acked-by: Christian König <christian.koenig@amd.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
arch/x86/ia32/ia32_aout.c
fs/binfmt_aout.c
fs/binfmt_elf.c

index 5e5b9fc2747ff3594b45576134bdb24dfb654f55..321d7b22ad2d13f643b99b003389f0ff5babf523 100644 (file)
@@ -293,7 +293,7 @@ static int load_aout_library(struct file *file)
        /* Now use mmap to map the library into memory. */
        error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
                        PROT_READ | PROT_WRITE | PROT_EXEC,
-                       MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_32BIT,
+                       MAP_FIXED | MAP_PRIVATE | MAP_32BIT,
                        N_TXTOFF(ex));
        retval = error;
        if (error != start_addr)
index 145917f734feb38d65aea1f88f5bacca27662059..d29de971d3f3d6a1c3270f8bd2d4ed67407a6d92 100644 (file)
@@ -309,7 +309,7 @@ static int load_aout_library(struct file *file)
        /* Now use mmap to map the library into memory. */
        error = vm_mmap(file, start_addr, ex.a_text + ex.a_data,
                        PROT_READ | PROT_WRITE | PROT_EXEC,
-                       MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE,
+                       MAP_FIXED | MAP_PRIVATE;
                        N_TXTOFF(ex));
        retval = error;
        if (error != start_addr)
index 439ed81e755af42d8fd5ee2b17db5dd3d6c01611..6d2c795336318b8c2abae9b71930cdc7635c060f 100644 (file)
@@ -1384,7 +1384,7 @@ static int load_elf_library(struct file *file)
                        (eppnt->p_filesz +
                         ELF_PAGEOFFSET(eppnt->p_vaddr)),
                        PROT_READ | PROT_WRITE | PROT_EXEC,
-                       MAP_FIXED_NOREPLACE | MAP_PRIVATE | MAP_DENYWRITE,
+                       MAP_FIXED_NOREPLACE | MAP_PRIVATE,
                        (eppnt->p_offset -
                         ELF_PAGEOFFSET(eppnt->p_vaddr)));
        if (error != ELF_PAGESTART(eppnt->p_vaddr))