mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
Kernel: sys$munmap() region splitting did not preserve "shared" flag
This was exploitable since the shared flag determines whether inode permission checks are applied in sys$mprotect(). The bug was pretty hard to spot due to default arguments being used instead. This patch removes the default arguments to make explicit at each call site what's being done.
This commit is contained in:
parent
e7183cc762
commit
a131927c75
Notes:
sideshowbarker
2024-07-18 22:50:38 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/a131927c753
4 changed files with 9 additions and 6 deletions
|
@ -127,7 +127,8 @@ Range Process::allocate_range(VirtualAddress vaddr, size_t size, size_t alignmen
|
|||
|
||||
Region& Process::allocate_split_region(const Region& source_region, const Range& range, size_t offset_in_vmobject)
|
||||
{
|
||||
auto& region = add_region(Region::create_user_accessible(this, range, source_region.vmobject(), offset_in_vmobject, source_region.name(), source_region.access()));
|
||||
auto& region = add_region(
|
||||
Region::create_user_accessible(this, range, source_region.vmobject(), offset_in_vmobject, source_region.name(), source_region.access(), source_region.is_cacheable(), source_region.is_shared()));
|
||||
region.set_mmap(source_region.is_mmap());
|
||||
region.set_stack(source_region.is_stack());
|
||||
size_t page_offset_in_source_region = (offset_in_vmobject - source_region.offset_in_vmobject()) / PAGE_SIZE;
|
||||
|
@ -144,7 +145,7 @@ KResultOr<Region*> Process::allocate_region(const Range& range, const String& na
|
|||
auto vmobject = AnonymousVMObject::create_with_size(range.size(), strategy);
|
||||
if (!vmobject)
|
||||
return ENOMEM;
|
||||
auto region = Region::create_user_accessible(this, range, vmobject.release_nonnull(), 0, name, prot_to_region_access_flags(prot));
|
||||
auto region = Region::create_user_accessible(this, range, vmobject.release_nonnull(), 0, name, prot_to_region_access_flags(prot), true, false);
|
||||
if (!region->map(page_directory()))
|
||||
return ENOMEM;
|
||||
return &add_region(move(region));
|
||||
|
|
|
@ -454,7 +454,7 @@ OwnPtr<Region> MemoryManager::allocate_kernel_region_with_vmobject(const Range&
|
|||
ScopedSpinLock lock(s_mm_lock);
|
||||
OwnPtr<Region> region;
|
||||
if (user_accessible)
|
||||
region = Region::create_user_accessible(nullptr, range, vmobject, 0, name, access, cacheable);
|
||||
region = Region::create_user_accessible(nullptr, range, vmobject, 0, name, access, cacheable, false);
|
||||
else
|
||||
region = Region::create_kernel_only(range, vmobject, 0, name, access, cacheable);
|
||||
if (region)
|
||||
|
|
|
@ -99,7 +99,8 @@ OwnPtr<Region> Region::clone(Process& new_owner)
|
|||
ASSERT(vmobject().is_shared_inode());
|
||||
|
||||
// Create a new region backed by the same VMObject.
|
||||
auto region = Region::create_user_accessible(&new_owner, m_range, m_vmobject, m_offset_in_vmobject, m_name, m_access);
|
||||
auto region = Region::create_user_accessible(
|
||||
&new_owner, m_range, m_vmobject, m_offset_in_vmobject, m_name, m_access, m_cacheable, m_shared);
|
||||
if (m_vmobject->is_anonymous())
|
||||
region->copy_purgeable_page_ranges(*this);
|
||||
region->set_mmap(m_mmap);
|
||||
|
@ -116,7 +117,8 @@ OwnPtr<Region> Region::clone(Process& new_owner)
|
|||
|
||||
// Set up a COW region. The parent (this) region becomes COW as well!
|
||||
remap();
|
||||
auto clone_region = Region::create_user_accessible(&new_owner, m_range, vmobject_clone.release_nonnull(), m_offset_in_vmobject, m_name, m_access);
|
||||
auto clone_region = Region::create_user_accessible(
|
||||
&new_owner, m_range, vmobject_clone.release_nonnull(), m_offset_in_vmobject, m_name, m_access, m_cacheable, m_shared);
|
||||
if (m_vmobject->is_anonymous())
|
||||
clone_region->copy_purgeable_page_ranges(*this);
|
||||
if (m_stack) {
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
Execute = 4,
|
||||
};
|
||||
|
||||
static NonnullOwnPtr<Region> create_user_accessible(Process*, const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, const StringView& name, u8 access, bool cacheable = true, bool shared = false);
|
||||
static NonnullOwnPtr<Region> create_user_accessible(Process*, const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, const StringView& name, u8 access, bool cacheable, bool shared);
|
||||
static NonnullOwnPtr<Region> create_kernel_only(const Range&, NonnullRefPtr<VMObject>, size_t offset_in_vmobject, const StringView& name, u8 access, bool cacheable = true);
|
||||
|
||||
~Region();
|
||||
|
|
Loading…
Reference in a new issue