mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 04:41:12 +00:00
kern: add new overflow checks on KMemoryRegions
This commit is contained in:
parent
748893fe77
commit
0a1465f198
8 changed files with 32 additions and 1 deletions
|
@ -112,7 +112,9 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
static ALWAYS_INLINE KVirtualAddress GetStackTopAddress(s32 core_id, KMemoryRegionType type) {
|
static ALWAYS_INLINE KVirtualAddress GetStackTopAddress(s32 core_id, KMemoryRegionType type) {
|
||||||
return Dereference(GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast<u32>(core_id))).GetEndAddress();
|
const auto ®ion = Dereference(GetVirtualMemoryRegionTree().FindByTypeAndAttribute(type, static_cast<u32>(core_id)));
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(region.GetEndAddress() != 0);
|
||||||
|
return region.GetEndAddress();
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
static ALWAYS_INLINE KMemoryRegionTree &GetVirtualMemoryRegionTree() { return s_virtual_tree; }
|
static ALWAYS_INLINE KMemoryRegionTree &GetVirtualMemoryRegionTree() { return s_virtual_tree; }
|
||||||
|
|
|
@ -93,6 +93,7 @@ namespace ams::kern {
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr ALWAYS_INLINE bool Contains(uintptr_t address) const {
|
constexpr ALWAYS_INLINE bool Contains(uintptr_t address) const {
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(this->GetEndAddress() != 0);
|
||||||
return this->GetAddress() <= address && address <= this->GetLastAddress();
|
return this->GetAddress() <= address && address <= this->GetLastAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,6 +182,9 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
const KMemoryRegion *region = KMemoryLayout::Find(KPhysicalAddress(address));
|
const KMemoryRegion *region = KMemoryLayout::Find(KPhysicalAddress(address));
|
||||||
if (AMS_LIKELY(region != nullptr)) {
|
if (AMS_LIKELY(region != nullptr)) {
|
||||||
if (AMS_LIKELY(region->IsDerivedFrom(KMemoryRegionType_MemoryController))) {
|
if (AMS_LIKELY(region->IsDerivedFrom(KMemoryRegionType_MemoryController))) {
|
||||||
|
/* Check the region is valid. */
|
||||||
|
MESOSPHERE_ABORT_UNLESS(region->GetEndAddress() != 0);
|
||||||
|
|
||||||
/* Get the offset within the region. */
|
/* Get the offset within the region. */
|
||||||
const size_t offset = address - region->GetAddress();
|
const size_t offset = address - region->GetAddress();
|
||||||
MESOSPHERE_ABORT_UNLESS(offset < region->GetSize());
|
MESOSPHERE_ABORT_UNLESS(offset < region->GetSize());
|
||||||
|
@ -210,6 +213,9 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
region->IsDerivedFrom(KMemoryRegionType_MemoryController0) ||
|
region->IsDerivedFrom(KMemoryRegionType_MemoryController0) ||
|
||||||
region->IsDerivedFrom(KMemoryRegionType_MemoryController1))
|
region->IsDerivedFrom(KMemoryRegionType_MemoryController1))
|
||||||
{
|
{
|
||||||
|
/* Check the region is valid. */
|
||||||
|
MESOSPHERE_ABORT_UNLESS(region->GetEndAddress() != 0);
|
||||||
|
|
||||||
/* Get the offset within the region. */
|
/* Get the offset within the region. */
|
||||||
const size_t offset = address - region->GetAddress();
|
const size_t offset = address - region->GetAddress();
|
||||||
MESOSPHERE_ABORT_UNLESS(offset < region->GetSize());
|
MESOSPHERE_ABORT_UNLESS(offset < region->GetSize());
|
||||||
|
@ -449,6 +455,8 @@ namespace ams::kern::board::nintendo::nx {
|
||||||
/* Configure the Kernel Carveout region. */
|
/* Configure the Kernel Carveout region. */
|
||||||
{
|
{
|
||||||
const auto carveout = KMemoryLayout::GetCarveoutRegionExtents();
|
const auto carveout = KMemoryLayout::GetCarveoutRegionExtents();
|
||||||
|
MESOSPHERE_ABORT_UNLESS(carveout.GetEndAddress() != 0);
|
||||||
|
|
||||||
smc::ConfigureCarveout(0, carveout.GetAddress(), carveout.GetSize());
|
smc::ConfigureCarveout(0, carveout.GetAddress(), carveout.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ namespace ams::kern {
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(start, size, phys_type, attr));
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetPhysicalMemoryRegionTree().Insert(start, size, phys_type, attr));
|
||||||
const KMemoryRegion *phys = KMemoryLayout::GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(phys_type, attr);
|
const KMemoryRegion *phys = KMemoryLayout::GetPhysicalMemoryRegionTree().FindByTypeAndAttribute(phys_type, attr);
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(phys != nullptr);
|
MESOSPHERE_INIT_ABORT_UNLESS(phys != nullptr);
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(phys->GetEndAddress() != 0);
|
||||||
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetVirtualMemoryRegionTree().Insert(phys->GetPairAddress(), size, virt_type, attr));
|
MESOSPHERE_INIT_ABORT_UNLESS(KMemoryLayout::GetVirtualMemoryRegionTree().Insert(phys->GetPairAddress(), size, virt_type, attr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,6 +105,7 @@ namespace ams::kern {
|
||||||
void SetupPoolPartitionMemoryRegions() {
|
void SetupPoolPartitionMemoryRegions() {
|
||||||
/* Start by identifying the extents of the DRAM memory region. */
|
/* Start by identifying the extents of the DRAM memory region. */
|
||||||
const auto dram_extents = KMemoryLayout::GetMainMemoryPhysicalExtents();
|
const auto dram_extents = KMemoryLayout::GetMainMemoryPhysicalExtents();
|
||||||
|
MESOSPHERE_INIT_ABORT_UNLESS(dram_extents.GetEndAddress() != 0);
|
||||||
|
|
||||||
/* Determine the end of the pool region. */
|
/* Determine the end of the pool region. */
|
||||||
const uintptr_t pool_end = dram_extents.GetEndAddress() - KTraceBufferSize;
|
const uintptr_t pool_end = dram_extents.GetEndAddress() - KTraceBufferSize;
|
||||||
|
|
|
@ -1807,6 +1807,9 @@ namespace ams::kern {
|
||||||
const KMemoryRegion *region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindFirstDerived(region_type);
|
const KMemoryRegion *region = KMemoryLayout::GetPhysicalMemoryRegionTree().FindFirstDerived(region_type);
|
||||||
R_UNLESS(region != nullptr, svc::ResultOutOfRange());
|
R_UNLESS(region != nullptr, svc::ResultOutOfRange());
|
||||||
|
|
||||||
|
/* Check that the region is valid. */
|
||||||
|
MESOSPHERE_ABORT_UNLESS(region->GetEndAddress() != 0);
|
||||||
|
|
||||||
/* Map the region. */
|
/* Map the region. */
|
||||||
R_TRY_CATCH(this->MapStatic(region->GetAddress(), region->GetSize(), perm)) {
|
R_TRY_CATCH(this->MapStatic(region->GetAddress(), region->GetSize(), perm)) {
|
||||||
R_CONVERT(svc::ResultInvalidAddress, svc::ResultOutOfRange())
|
R_CONVERT(svc::ResultInvalidAddress, svc::ResultOutOfRange())
|
||||||
|
|
|
@ -207,6 +207,7 @@ namespace ams::kern {
|
||||||
Result KThread::InitializeThread(KThread *thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess *owner, ThreadType type) {
|
Result KThread::InitializeThread(KThread *thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess *owner, ThreadType type) {
|
||||||
/* Get stack region for the thread. */
|
/* Get stack region for the thread. */
|
||||||
const auto &stack_region = KMemoryLayout::GetKernelStackRegion();
|
const auto &stack_region = KMemoryLayout::GetKernelStackRegion();
|
||||||
|
MESOSPHERE_ABORT_UNLESS(stack_region.GetEndAddress() != 0);
|
||||||
|
|
||||||
/* Allocate a page to use as the thread. */
|
/* Allocate a page to use as the thread. */
|
||||||
KPageBuffer *page = KPageBuffer::Allocate();
|
KPageBuffer *page = KPageBuffer::Allocate();
|
||||||
|
|
|
@ -52,6 +52,8 @@ namespace ams::kern {
|
||||||
/* Initialize the memory manager and the KPageBuffer slabheap. */
|
/* Initialize the memory manager and the KPageBuffer slabheap. */
|
||||||
{
|
{
|
||||||
const auto &management_region = KMemoryLayout::GetPoolManagementRegion();
|
const auto &management_region = KMemoryLayout::GetPoolManagementRegion();
|
||||||
|
MESOSPHERE_ABORT_UNLESS(management_region.GetEndAddress() != 0);
|
||||||
|
|
||||||
Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize());
|
Kernel::GetMemoryManager().Initialize(management_region.GetAddress(), management_region.GetSize());
|
||||||
init::InitializeKPageBufferSlabHeap();
|
init::InitializeKPageBufferSlabHeap();
|
||||||
}
|
}
|
||||||
|
@ -68,6 +70,8 @@ namespace ams::kern {
|
||||||
/* Initialize the Dynamic Slab Heaps. */
|
/* Initialize the Dynamic Slab Heaps. */
|
||||||
{
|
{
|
||||||
const auto &pt_heap_region = KMemoryLayout::GetPageTableHeapRegion();
|
const auto &pt_heap_region = KMemoryLayout::GetPageTableHeapRegion();
|
||||||
|
MESOSPHERE_ABORT_UNLESS(pt_heap_region.GetEndAddress() != 0);
|
||||||
|
|
||||||
Kernel::InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize());
|
Kernel::InitializeResourceManagers(pt_heap_region.GetAddress(), pt_heap_region.GetSize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -124,6 +128,13 @@ namespace ams::kern {
|
||||||
|
|
||||||
/* Resume all threads suspended while we initialized. */
|
/* Resume all threads suspended while we initialized. */
|
||||||
KThread::ResumeThreadsSuspendedForInit();
|
KThread::ResumeThreadsSuspendedForInit();
|
||||||
|
|
||||||
|
/* Validate that all reserved dram blocks are valid. */
|
||||||
|
for (const auto ®ion : KMemoryLayout::GetPhysicalMemoryRegionTree()) {
|
||||||
|
if (region.IsDerivedFrom(KMemoryRegionType_DramReservedBase)) {
|
||||||
|
MESOSPHERE_ABORT_UNLESS(region.GetEndAddress() != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
cpu::SynchronizeAllCores();
|
cpu::SynchronizeAllCores();
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,9 @@ namespace ams::kern::svc {
|
||||||
/* Ensure that we found the region. */
|
/* Ensure that we found the region. */
|
||||||
R_UNLESS(region != nullptr, svc::ResultNotFound());
|
R_UNLESS(region != nullptr, svc::ResultNotFound());
|
||||||
|
|
||||||
|
/* Chcek that the region is valid. */
|
||||||
|
MESOSPHERE_ABORT_UNLESS(region->GetEndAddress() != 0);
|
||||||
|
|
||||||
R_TRY(pt.QueryStaticMapping(std::addressof(found_address), region->GetAddress(), region->GetSize()));
|
R_TRY(pt.QueryStaticMapping(std::addressof(found_address), region->GetAddress(), region->GetSize()));
|
||||||
found_size = region->GetSize();
|
found_size = region->GetSize();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue