Skip to content

Commit

Permalink
Kernel: Make Region weakable and use WeakPtr<Region> instead of Region*
Browse files Browse the repository at this point in the history
This turns use-after-free bugs into null pointer dereferences instead.
  • Loading branch information
awesomekling committed Feb 24, 2020
1 parent 79576f9 commit 30a8991
Show file tree
Hide file tree
Showing 5 changed files with 14 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Kernel/Process.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ Region* Process::region_from_range(const Range& range)
for (auto& region : m_regions) {
if (region.vaddr() == range.base() && region.size() == size) {
m_region_lookup_cache.range = range;
m_region_lookup_cache.region = &region;
m_region_lookup_cache.region = region.make_weak_ptr();
return &region;
}
}
Expand Down
3 changes: 2 additions & 1 deletion Kernel/Process.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <AK/InlineLinkedList.h>
#include <AK/NonnullOwnPtrVector.h>
#include <AK/String.h>
#include <AK/WeakPtr.h>
#include <Kernel/FileSystem/InodeMetadata.h>
#include <Kernel/Forward.h>
#include <Kernel/Lock.h>
Expand Down Expand Up @@ -479,7 +480,7 @@ class Process : public InlineLinkedListNode<Process> {
NonnullOwnPtrVector<Region> m_regions;
struct RegionLookupCache {
Range range;
Region* region { nullptr };
WeakPtr<Region> region;
};
RegionLookupCache m_region_lookup_cache;

Expand Down
9 changes: 5 additions & 4 deletions Kernel/SharedBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,13 @@ void* SharedBuffer::ref_for_process_and_get_address(Process& process)

for (auto& ref : m_refs) {
if (ref.pid == process.pid()) {
ref.count++;
m_total_refs++;
if (ref.region == nullptr) {
ref.region = process.allocate_region_with_vmobject(VirtualAddress(), size(), m_vmobject, 0, "SharedBuffer", PROT_READ | (m_writable ? PROT_WRITE : 0));
if (!ref.region) {
auto* region = process.allocate_region_with_vmobject(VirtualAddress(), size(), m_vmobject, 0, "SharedBuffer", PROT_READ | (m_writable ? PROT_WRITE : 0));
ref.region = region->make_weak_ptr();
ref.region->set_shared(true);
}
ref.count++;
m_total_refs++;
sanity_check("ref_for_process_and_get_address");
return ref.region->vaddr().as_ptr();
}
Expand Down
3 changes: 2 additions & 1 deletion Kernel/SharedBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#pragma once

#include <AK/OwnPtr.h>
#include <AK/WeakPtr.h>
#include <Kernel/VM/MemoryManager.h>
#include <Kernel/VM/PurgeableVMObject.h>

Expand All @@ -42,7 +43,7 @@ class SharedBuffer {

pid_t pid;
unsigned count { 0 };
Region* region { nullptr };
WeakPtr<Region> region;
};

public:
Expand Down
5 changes: 4 additions & 1 deletion Kernel/VM/Region.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include <AK/InlineLinkedList.h>
#include <AK/String.h>
#include <AK/Weakable.h>
#include <Kernel/Heap/SlabAllocator.h>
#include <Kernel/VM/RangeAllocator.h>

Expand All @@ -41,7 +42,9 @@ enum class PageFaultResponse {
Continue,
};

class Region final : public InlineLinkedListNode<Region> {
class Region final
: public InlineLinkedListNode<Region>
, public Weakable<Region> {
friend class MemoryManager;

MAKE_SLAB_ALLOCATED(Region)
Expand Down

0 comments on commit 30a8991

Please sign in to comment.