kern: finish shadow stack region, 64k page process segregation implementation, fix some long-standing issues

This commit is contained in:
Alula
2026-09-15 17:03:11 +02:00
parent 289ba7104e
commit 7e58f5fbae
9 changed files with 132 additions and 188 deletions

View File

@@ -19,6 +19,7 @@
#include <mesosphere/kern_k_page_table_base.hpp>
#include <mesosphere/kern_k_page_group.hpp>
#include <mesosphere/kern_k_page_table_manager.hpp>
#include <mesosphere/init/kern_init_slab_setup.hpp>
namespace ams::kern::arch::arm64 {

View File

@@ -32,6 +32,11 @@ namespace ams::kern::arch::arm64 {
R_RETURN(m_page_table.InitializeForProcess(flags, from_back, pool, code_address, code_size, system_resource, resource_limit, process_index));
}
static ALWAYS_INLINE u64 GetProcessTcrEl1(size_t process_index) {
/* The kernel's root table is entry zero; processes are indexed from one. */
return KPageTable::GetTcrEL1Entry(process_index + 1);
}
void Finalize() { m_page_table.Finalize(); }
ALWAYS_INLINE KScopedLightLock AcquireDeviceMapLock() {
@@ -302,6 +307,10 @@ namespace ams::kern::arch::arm64 {
bool CanContain(KProcessAddress addr, size_t size, KMemoryState state) const { return m_page_table.CanContain(addr, size, state); }
bool CanContain(KProcessAddress addr, size_t size, ams::svc::MemoryState state) const { return m_page_table.CanContain(addr, size, state); }
bool IsInShadowStackRegion(KProcessAddress addr, size_t size) const { return m_page_table.IsInShadowStackRegion(addr, size); }
bool IsInShadowStackRegion(KProcessAddress addr) const { return m_page_table.IsInShadowStackRegion(addr); }
bool IsSafeUserPointer(KProcessAddress addr, size_t size) const { return m_page_table.IsSafeUserPointer(addr, size); }
KProcessAddress GetAddressSpaceStart() const { return m_page_table.GetAddressSpaceStart(); }
KProcessAddress GetShadowStackRegionStart() const { return m_page_table.GetShadowStackRegionStart(); }
KProcessAddress GetHeapRegionStart() const { return m_page_table.GetHeapRegionStart(); }

View File

@@ -77,7 +77,7 @@ namespace ams::kern::arch::arm64 {
static bool CopyMemoryFromUserSize32BitWithSupervisorAccess(void *dst, const void *src) {
/* Check that the address is within the valid userspace range. */
if (const uintptr_t src_uptr = reinterpret_cast<uintptr_t>(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion39Size) {
if (const uintptr_t src_uptr = reinterpret_cast<uintptr_t>(src); src_uptr < ams::svc::AddressNullGuard32Size || (src_uptr + sizeof(u32) - 1) >= ams::svc::AddressMemoryRegion42Size) {
return false;
}

View File

@@ -249,7 +249,15 @@ namespace ams::kern {
}
constexpr bool IsInShadowStackRegion(KProcessAddress addr, size_t size) const {
return this->Contains(addr, size) && m_region_starts[RegionType_ShadowStack] <= addr && addr + size - 1 <= m_region_ends[RegionType_ShadowStack] - 1;
const auto start = m_region_starts[RegionType_ShadowStack];
const auto end = m_region_ends[RegionType_ShadowStack];
return start != end && addr < end && start < addr + size;
}
constexpr bool IsInShadowStackRegion(KProcessAddress addr) const {
const auto start = m_region_starts[RegionType_ShadowStack];
const auto end = m_region_ends[RegionType_ShadowStack];
return start <= addr && addr < end;
}
constexpr bool IsSafeUserPointer(KProcessAddress addr, size_t size) const {