From 5a9b7c0258ddc2f9d95d3eacbd3b4d9bb79509cb Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Wed, 4 Mar 2026 14:15:33 +0100 Subject: [PATCH] Implement canonical address validation routine --- xtoskrnl/includes/mm/amd64/pagemap.hh | 1 + xtoskrnl/includes/mm/amd64/paging.hh | 1 + xtoskrnl/includes/mm/i686/pagemap.hh | 1 + xtoskrnl/includes/mm/i686/paging.hh | 1 + xtoskrnl/mm/amd64/pagemap.cc | 23 +++++++++++++++++++++++ xtoskrnl/mm/i686/pagemap.cc | 18 ++++++++++++++++++ xtoskrnl/mm/paging.cc | 18 ++++++++++++++++++ 7 files changed, 63 insertions(+) diff --git a/xtoskrnl/includes/mm/amd64/pagemap.hh b/xtoskrnl/includes/mm/amd64/pagemap.hh index 0d56e85..9501999 100644 --- a/xtoskrnl/includes/mm/amd64/pagemap.hh +++ b/xtoskrnl/includes/mm/amd64/pagemap.hh @@ -23,6 +23,7 @@ namespace MM public: XTAPI PMMPTE AdvancePte(IN PMMPTE Pte, IN LONG Count); + XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress); XTAPI VOID ClearPte(IN PMMPTE PtePointer); XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte); XTAPI PMMPTE GetNextPte(IN PMMPTE Pte); diff --git a/xtoskrnl/includes/mm/amd64/paging.hh b/xtoskrnl/includes/mm/amd64/paging.hh index a0e5062..da23159 100644 --- a/xtoskrnl/includes/mm/amd64/paging.hh +++ b/xtoskrnl/includes/mm/amd64/paging.hh @@ -23,6 +23,7 @@ namespace MM public: STATIC XTAPI PMMPTE AdvancePte(IN PMMPTE Pte, IN LONG Count); + STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress); STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer); STATIC XTAPI VOID FlushTlb(VOID); STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte); diff --git a/xtoskrnl/includes/mm/i686/pagemap.hh b/xtoskrnl/includes/mm/i686/pagemap.hh index 3552cda..eff6ab5 100644 --- a/xtoskrnl/includes/mm/i686/pagemap.hh +++ b/xtoskrnl/includes/mm/i686/pagemap.hh @@ -23,6 +23,7 @@ namespace MM public: VIRTUAL XTAPI PMMPTE AdvancePte(IN PMMPTE Pte, IN ULONG Count) = 0; + XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress); VIRTUAL XTAPI VOID ClearPte(IN PMMPTE PtePointer) = 0; VIRTUAL XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte) = 0; VIRTUAL XTAPI PMMPTE GetNextPte(IN PMMPTE Pte) = 0; diff --git a/xtoskrnl/includes/mm/i686/paging.hh b/xtoskrnl/includes/mm/i686/paging.hh index cdc95ab..e2d8fd2 100644 --- a/xtoskrnl/includes/mm/i686/paging.hh +++ b/xtoskrnl/includes/mm/i686/paging.hh @@ -23,6 +23,7 @@ namespace MM public: STATIC XTAPI PMMPTE AdvancePte(IN PMMPTE Pte, IN LONG Count); + STATIC XTAPI BOOLEAN CanonicalAddress(IN PVOID VirtualAddress); STATIC XTAPI VOID ClearPte(IN PMMPTE PtePointer); STATIC XTAPI VOID FlushTlb(VOID); STATIC XTAPI ULONG_PTR GetNextEntry(IN PMMPTE Pte); diff --git a/xtoskrnl/mm/amd64/pagemap.cc b/xtoskrnl/mm/amd64/pagemap.cc index 2d349a3..2f2bda4 100644 --- a/xtoskrnl/mm/amd64/pagemap.cc +++ b/xtoskrnl/mm/amd64/pagemap.cc @@ -31,6 +31,29 @@ MM::PageMap::AdvancePte(IN PMMPTE Pte, return (PMMPTE)((ULONG_PTR)Pte + (Count * sizeof(MMPTE))); } +/** + * Checks if the given address is canonical. + * + * @param VirtualAddress + * Specifies the virtual address to check. + * + * @return This routine returns TRUE if the address is canonical, FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MM::PageMap::CanonicalAddress(IN PVOID VirtualAddress) +{ + ULONG Shift; + + /* Calculate the number of unused upper bits based on the paging mode */ + Shift = 64 - PageMapInfo.VaBits; + + /* Sign-extend via arithmetic shifts to verify the canonical form */ + return ((((LONGLONG)VirtualAddress << Shift) >> Shift) == (LONGLONG)VirtualAddress); +} + /** * Clears the contents of a page table entry (PTE). * diff --git a/xtoskrnl/mm/i686/pagemap.cc b/xtoskrnl/mm/i686/pagemap.cc index d4db9b7..c7c0043 100644 --- a/xtoskrnl/mm/i686/pagemap.cc +++ b/xtoskrnl/mm/i686/pagemap.cc @@ -9,6 +9,24 @@ #include +/** + * Checks if the given address is canonical. + * + * @param VirtualAddress + * Specifies the virtual address to check. + * + * @return This routine returns TRUE, as all addresses in i686 are canonical. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MM::PageMap::CanonicalAddress(IN PVOID VirtualAddress) +{ + /* All addresses in i686 are canonical */ + return TRUE; +} + /** * Gets Page Map Level (PML) for current paging mode. * diff --git a/xtoskrnl/mm/paging.cc b/xtoskrnl/mm/paging.cc index 69305a6..053681c 100644 --- a/xtoskrnl/mm/paging.cc +++ b/xtoskrnl/mm/paging.cc @@ -31,6 +31,24 @@ MM::Paging::AdvancePte(IN PMMPTE Pte, return PmlRoutines->AdvancePte(Pte, Count); } +/** + * Checks if the given address is canonical. + * + * @param VirtualAddress + * Specifies the virtual address to check. + * + * @return This routine returns TRUE if the address is canonical, FALSE otherwise. + * + * @since XT 1.0 + */ +XTAPI +BOOLEAN +MM::Paging::CanonicalAddress(IN PVOID VirtualAddress) +{ + /* Return canonical address status */ + return PmlRoutines->CanonicalAddress(VirtualAddress); +} + /** * Clears the contents of a page table entry (PTE). *