mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-23 18:02:05 -05:00
Kernel: Check wxallowed mount flag when validating mmap call
This commit is contained in:
parent
3f391d80c4
commit
479929b06c
1 changed files with 10 additions and 7 deletions
|
@ -69,7 +69,7 @@ static bool should_make_executable_exception_for_dynamic_loader(bool make_readab
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool validate_mmap_prot(int prot, bool map_stack, bool map_anonymous, Memory::Region const* region = nullptr)
|
||||
static bool validate_mmap_prot(const Process& process, int prot, bool map_stack, bool map_anonymous, Memory::Region const* region = nullptr)
|
||||
{
|
||||
bool make_readable = prot & PROT_READ;
|
||||
bool make_writable = prot & PROT_WRITE;
|
||||
|
@ -78,10 +78,13 @@ static bool validate_mmap_prot(int prot, bool map_stack, bool map_anonymous, Mem
|
|||
if (map_anonymous && make_executable)
|
||||
return false;
|
||||
|
||||
if (make_writable && make_executable)
|
||||
if (map_stack && make_executable)
|
||||
return false;
|
||||
|
||||
if (map_stack && make_executable)
|
||||
if (executable()->mount_flags() & MS_WXALLOWED)
|
||||
return true;
|
||||
|
||||
if (make_writable && make_executable)
|
||||
return false;
|
||||
|
||||
if (region) {
|
||||
|
@ -177,7 +180,7 @@ ErrorOr<FlatPtr> Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> use
|
|||
if ((map_fixed || map_fixed_noreplace) && map_randomized)
|
||||
return EINVAL;
|
||||
|
||||
if (!validate_mmap_prot(prot, map_stack, map_anonymous))
|
||||
if (!validate_mmap_prot(*this, prot, map_stack, map_anonymous))
|
||||
return EINVAL;
|
||||
|
||||
if (map_stack && (!map_private || !map_anonymous))
|
||||
|
@ -270,7 +273,7 @@ ErrorOr<FlatPtr> Process::sys$mprotect(Userspace<void*> addr, size_t size, int p
|
|||
if (auto* whole_region = address_space().find_region_from_range(range_to_mprotect)) {
|
||||
if (!whole_region->is_mmap())
|
||||
return EPERM;
|
||||
if (!validate_mmap_prot(prot, whole_region->is_stack(), whole_region->vmobject().is_anonymous(), whole_region))
|
||||
if (!validate_mmap_prot(*this, prot, whole_region->is_stack(), whole_region->vmobject().is_anonymous(), whole_region))
|
||||
return EINVAL;
|
||||
if (whole_region->access() == Memory::prot_to_region_access_flags(prot))
|
||||
return 0;
|
||||
|
@ -290,7 +293,7 @@ ErrorOr<FlatPtr> Process::sys$mprotect(Userspace<void*> addr, size_t size, int p
|
|||
if (auto* old_region = address_space().find_region_containing(range_to_mprotect)) {
|
||||
if (!old_region->is_mmap())
|
||||
return EPERM;
|
||||
if (!validate_mmap_prot(prot, old_region->is_stack(), old_region->vmobject().is_anonymous(), old_region))
|
||||
if (!validate_mmap_prot(*this, prot, old_region->is_stack(), old_region->vmobject().is_anonymous(), old_region))
|
||||
return EINVAL;
|
||||
if (old_region->access() == Memory::prot_to_region_access_flags(prot))
|
||||
return 0;
|
||||
|
@ -330,7 +333,7 @@ ErrorOr<FlatPtr> Process::sys$mprotect(Userspace<void*> addr, size_t size, int p
|
|||
for (const auto* region : regions) {
|
||||
if (!region->is_mmap())
|
||||
return EPERM;
|
||||
if (!validate_mmap_prot(prot, region->is_stack(), region->vmobject().is_anonymous(), region))
|
||||
if (!validate_mmap_prot(*this, prot, region->is_stack(), region->vmobject().is_anonymous(), region))
|
||||
return EINVAL;
|
||||
if (region->vmobject().is_inode()
|
||||
&& !validate_inode_mmap_prot(*this, prot, static_cast<Memory::InodeVMObject const&>(region->vmobject()).inode(), region->is_shared())) {
|
||||
|
|
Loading…
Add table
Reference in a new issue