Commit d8e7cb39 authored by Alexey Dobriyan's avatar Alexey Dobriyan Committed by Linus Torvalds

fs/binfmt_elf.c: extract PROT_* calculations

There are two places where mapping protections are calculated: one for
executable, another one for interpreter -- take them out.

ELF read and execute permissions are interchanged with Linux PROT_READ
and PROT_EXEC, microoptimizations are welcome!

Link: http://lkml.kernel.org/r/20190417213413.GB26474@avx2Signed-off-by: default avatarAlexey Dobriyan <adobriyan@gmail.com>
Reviewed-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 85264316
...@@ -524,6 +524,19 @@ static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp, ...@@ -524,6 +524,19 @@ static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp,
#endif /* !CONFIG_ARCH_BINFMT_ELF_STATE */ #endif /* !CONFIG_ARCH_BINFMT_ELF_STATE */
static inline int make_prot(u32 p_flags)
{
int prot = 0;
if (p_flags & PF_R)
prot |= PROT_READ;
if (p_flags & PF_W)
prot |= PROT_WRITE;
if (p_flags & PF_X)
prot |= PROT_EXEC;
return prot;
}
/* This is much more generalized than the library routine read function, /* This is much more generalized than the library routine read function,
so we keep this separate. Technically the library read function so we keep this separate. Technically the library read function
is only provided so that we can read a.out libraries that have is only provided so that we can read a.out libraries that have
...@@ -563,16 +576,10 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex, ...@@ -563,16 +576,10 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) { for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) {
if (eppnt->p_type == PT_LOAD) { if (eppnt->p_type == PT_LOAD) {
int elf_type = MAP_PRIVATE | MAP_DENYWRITE; int elf_type = MAP_PRIVATE | MAP_DENYWRITE;
int elf_prot = 0; int elf_prot = make_prot(eppnt->p_flags);
unsigned long vaddr = 0; unsigned long vaddr = 0;
unsigned long k, map_addr; unsigned long k, map_addr;
if (eppnt->p_flags & PF_R)
elf_prot = PROT_READ;
if (eppnt->p_flags & PF_W)
elf_prot |= PROT_WRITE;
if (eppnt->p_flags & PF_X)
elf_prot |= PROT_EXEC;
vaddr = eppnt->p_vaddr; vaddr = eppnt->p_vaddr;
if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) if (interp_elf_ex->e_type == ET_EXEC || load_addr_set)
elf_type |= MAP_FIXED_NOREPLACE; elf_type |= MAP_FIXED_NOREPLACE;
...@@ -891,7 +898,7 @@ static int load_elf_binary(struct linux_binprm *bprm) ...@@ -891,7 +898,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
the correct location in memory. */ the correct location in memory. */
for(i = 0, elf_ppnt = elf_phdata; for(i = 0, elf_ppnt = elf_phdata;
i < loc->elf_ex.e_phnum; i++, elf_ppnt++) { i < loc->elf_ex.e_phnum; i++, elf_ppnt++) {
int elf_prot = 0, elf_flags, elf_fixed = MAP_FIXED_NOREPLACE; int elf_prot, elf_flags, elf_fixed = MAP_FIXED_NOREPLACE;
unsigned long k, vaddr; unsigned long k, vaddr;
unsigned long total_size = 0; unsigned long total_size = 0;
...@@ -932,12 +939,7 @@ static int load_elf_binary(struct linux_binprm *bprm) ...@@ -932,12 +939,7 @@ static int load_elf_binary(struct linux_binprm *bprm)
elf_fixed = MAP_FIXED; elf_fixed = MAP_FIXED;
} }
if (elf_ppnt->p_flags & PF_R) elf_prot = make_prot(elf_ppnt->p_flags);
elf_prot |= PROT_READ;
if (elf_ppnt->p_flags & PF_W)
elf_prot |= PROT_WRITE;
if (elf_ppnt->p_flags & PF_X)
elf_prot |= PROT_EXEC;
elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE; elf_flags = MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment