diff options
author | alc <alc@FreeBSD.org> | 2017-06-28 05:28:15 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2017-06-28 05:28:15 +0000 |
commit | ecb5a7e5f9dcad755b6f7a80001364bf3741b617 (patch) | |
tree | e84d9d4254cb3160014bd223dfe7be456aa877cc | |
parent | eb68a05ac0b7244bce89dd423945345403220149 (diff) | |
download | FreeBSD-src-ecb5a7e5f9dcad755b6f7a80001364bf3741b617.zip FreeBSD-src-ecb5a7e5f9dcad755b6f7a80001364bf3741b617.tar.gz |
MFC r315518
Avoid unnecessary calls to vm_map_protect() in elf_load_section().
Typically, when elf_load_section() unconditionally passed VM_PROT_ALL to
elf_map_insert(), it was needlessly enabling execute access on the
mapping, and it would later have to call vm_map_protect() to correct the
mapping's access rights. Now, instead, elf_load_section() always passes
its parameter "prot" to elf_map_insert(). So, elf_load_section() must
only call vm_map_protect() if it needs to remove the write access that
was temporarily granted to perform a copyout().
Approved by: re (kib)
-rw-r--r-- | sys/kern/imgact_elf.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index 6ae6d67..f7bbdcf 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -596,7 +596,7 @@ __elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset, /* This had damn well better be true! */ if (map_len != 0) { rv = __elfN(map_insert)(imgp, map, NULL, 0, map_addr, - map_addr + map_len, VM_PROT_ALL, 0); + map_addr + map_len, prot, 0); if (rv != KERN_SUCCESS) return (EINVAL); } @@ -617,10 +617,12 @@ __elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset, } /* - * set it to the specified protection. + * Remove write access to the page if it was only granted by map_insert + * to allow copyout. */ - vm_map_protect(map, trunc_page(map_addr), round_page(map_addr + - map_len), prot, FALSE); + if ((prot & VM_PROT_WRITE) == 0) + vm_map_protect(map, trunc_page(map_addr), round_page(map_addr + + map_len), prot, FALSE); return (0); } |