Kernel: Don't access directory table of uninitialized PageDirectory

PageDirectory gets initialized step-by-step in
PageDirectory::try_create_for_userspace(). This initialization may fail
anywhere in this function - for example, we may not be able to
allocate a directory table, in which case
PageDirectory::try_create_for_userspace() will return a null pointer.
We recognize this condition and early-return ENOMEM. However, at this
point, we need to correctly destruct the only partially initialized
PageDirectory. Previously, PageDirectory::~PageDirectory() would assume
that the object it was destructing was always fully initialized. It now
uses the new helper PageDirectory::is_cr3_initialized() to correctly
recognize when the directory table was not yet initialized. This helper
checks if the pointer to the directory table is null. Only if it is not
null does the destructor try to fetch the directory table using
PageDirectory::cr3().
This commit is contained in:
creator1creeper1 2022-01-16 17:03:06 +01:00 committed by Brian Gianforcaro
parent 3a6d4d14e1
commit 326c6130a5
Notes: sideshowbarker 2024-07-17 20:44:46 +09:00
2 changed files with 13 additions and 2 deletions

View File

@ -150,8 +150,10 @@ UNMAP_AFTER_INIT void PageDirectory::allocate_kernel_directory()
PageDirectory::~PageDirectory()
{
SpinlockLocker lock(s_mm_lock);
cr3_map().remove(cr3());
if (is_cr3_initialized()) {
SpinlockLocker lock(s_mm_lock);
cr3_map().remove(cr3());
}
}
}

View File

@ -37,6 +37,15 @@ public:
#endif
}
bool is_cr3_initialized() const
{
#if ARCH(X86_64)
return m_pml4t;
#else
return m_directory_table;
#endif
}
VirtualRangeAllocator& range_allocator() { return m_range_allocator; }
VirtualRangeAllocator const& range_allocator() const { return m_range_allocator; }