Skip to content

Commit

Permalink
Kernel: Disallow mapping anonymous memory as executable
Browse files Browse the repository at this point in the history
This adds another layer of defense against introducing new code into a
running process. The only permitted way of doing so is by mmapping an
open file with PROT_READ | PROT_EXEC.

This does make any future JIT implementations slightly more complicated
but I think it's a worthwhile trade-off at this point. :^)
  • Loading branch information
awesomekling committed Jan 29, 2021
1 parent af3d3c5 commit 51df445
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions Kernel/Syscalls/mmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,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, const Region* region = nullptr, bool* is_making_executable_exception_for_dynamic_loader = nullptr)
static bool validate_mmap_prot(int prot, bool map_stack, bool map_anonymous, const Region* region = nullptr, bool* is_making_executable_exception_for_dynamic_loader = nullptr)
{
if (is_making_executable_exception_for_dynamic_loader)
*is_making_executable_exception_for_dynamic_loader = false;
Expand All @@ -93,6 +93,9 @@ static bool validate_mmap_prot(int prot, bool map_stack, const Region* region =
bool make_writable = prot & PROT_WRITE;
bool make_executable = prot & PROT_EXEC;

if (map_anonymous && make_executable)
return false;

if (make_writable && make_executable)
return false;

Expand Down Expand Up @@ -197,7 +200,7 @@ void* Process::sys$mmap(Userspace<const Syscall::SC_mmap_params*> user_params)
if (map_fixed && map_randomized)
return (void*)-EINVAL;

if (!validate_mmap_prot(prot, map_stack))
if (!validate_mmap_prot(prot, map_anonymous, map_stack))
return (void*)-EINVAL;

if (map_stack && (!map_private || !map_anonymous))
Expand Down Expand Up @@ -283,7 +286,7 @@ int Process::sys$mprotect(void* addr, size_t size, int prot)
if (!whole_region->is_mmap())
return -EPERM;
bool is_making_executable_exception_for_dynamic_loader = false;
if (!validate_mmap_prot(prot, whole_region->is_stack(), whole_region, &is_making_executable_exception_for_dynamic_loader))
if (!validate_mmap_prot(prot, whole_region->is_stack(), whole_region->vmobject().is_anonymous(), whole_region, &is_making_executable_exception_for_dynamic_loader))
return -EINVAL;
if (whole_region->access() == prot_to_region_access_flags(prot))
return 0;
Expand All @@ -307,7 +310,7 @@ int Process::sys$mprotect(void* addr, size_t size, int prot)
if (!old_region->is_mmap())
return -EPERM;
bool is_making_executable_exception_for_dynamic_loader = false;
if (!validate_mmap_prot(prot, old_region->is_stack(), old_region, &is_making_executable_exception_for_dynamic_loader))
if (!validate_mmap_prot(prot, old_region->is_stack(), old_region->vmobject().is_anonymous(), old_region, &is_making_executable_exception_for_dynamic_loader))
return -EINVAL;
if (old_region->access() == prot_to_region_access_flags(prot))
return 0;
Expand Down

0 comments on commit 51df445

Please sign in to comment.