From 7161fb705403c28b0e9d3a998d21c40095c73eb6 Mon Sep 17 00:00:00 2001 From: Weiteng Chen Date: Mon, 24 Aug 2026 17:46:13 -0700 Subject: [PATCH 1/3] Improve Windows virtual memory fidelity --- litebox_shim_windows/src/syscalls/mm.rs | 208 ++++++++++++++++++++++-- 1 file changed, 190 insertions(+), 18 deletions(-) diff --git a/litebox_shim_windows/src/syscalls/mm.rs b/litebox_shim_windows/src/syscalls/mm.rs index 7f62954a1..3305c9803 100644 --- a/litebox_shim_windows/src/syscalls/mm.rs +++ b/litebox_shim_windows/src/syscalls/mm.rs @@ -37,6 +37,7 @@ bitflags::bitflags! { const PAGE_GUARD = 0x100; const PAGE_NOCACHE = 0x200; const PAGE_WRITECOMBINE = 0x400; + const PAGE_TARGETS_INVALID = 0x40000000; } } @@ -52,10 +53,19 @@ impl PageProtection { let guard = self.contains(Self::PAGE_GUARD); let nocache = self.contains(Self::PAGE_NOCACHE); let writecombine = self.contains(Self::PAGE_WRITECOMBINE); + let targets_invalid = self.contains(Self::PAGE_TARGETS_INVALID); + let executable = matches!( + self.base(), + value if value == Self::PAGE_EXECUTE.bits() + || value == Self::PAGE_EXECUTE_READ.bits() + || value == Self::PAGE_EXECUTE_READWRITE.bits() + || value == Self::PAGE_EXECUTE_WRITECOPY.bits() + ); !(noaccess && (guard || nocache || writecombine) || guard && (nocache || writecombine) - || nocache && writecombine) + || nocache && writecombine + || targets_invalid && !executable) } } @@ -286,6 +296,14 @@ impl Task { let Some(size) = region_size.read_at_offset(0) else { return NtStatus::ACCESS_VIOLATION; }; + litebox_util_log::debug!( + base:% = format_args!("{base:#x}"), + size, + zero_bits:% = format_args!("{zero_bits:#x}"), + allocation_type:% = format_args!("{allocation_type:#x}"), + protect:% = format_args!("{protect:#x}"); + "NtAllocateVirtualMemory request" + ); if base_address.write_at_offset(0, base).is_none() || region_size.write_at_offset(0, size).is_none() { @@ -303,6 +321,14 @@ impl Task { || (zero_bits > 21 && zero_bits < 32) || (zero_bits != 0 && base != 0) { + litebox_util_log::debug!( + base:% = format_args!("{base:#x}"), + size, + zero_bits:% = format_args!("{zero_bits:#x}"), + allocation_type:% = format_args!("{:#x}", allocation_type.bits()), + protect:% = format_args!("{protect:#x}"); + "Rejected NtAllocateVirtualMemory parameters" + ); return NtStatus::INVALID_PARAMETER; } if allocation_type.contains(AllocationType::MEM_RESET) { @@ -452,13 +478,15 @@ impl Task { base_address: MutPtr, region_size: MutPtr, ) -> NtStatus { - if find_private_virtual_allocation( - &self.process.virtual_allocations, - aligned_base, - aligned_len, - ) - .is_none() - { + let Some(allocation) = + find_virtual_allocation(&self.process.virtual_allocations, aligned_base, aligned_len) + else { + return NtStatus::INVALID_PARAMETER; + }; + if !matches!( + allocation.type_, + MemoryType::MEM_PRIVATE | MemoryType::MEM_MAPPED + ) { return NtStatus::INVALID_PARAMETER; } if update_permissions( @@ -519,7 +547,7 @@ impl Task { } let Some((aligned_base, aligned_len)) = - free_region(&self.process.virtual_allocations, base, size, free_type) + free_region(&self.process.virtual_allocations, base, size) else { return NtStatus::INVALID_PARAMETER; }; @@ -548,10 +576,11 @@ impl Task { if unsafe { self.global.page_manager.remove_pages(ptr, aligned_len) }.is_err() { return NtStatus::UNABLE_TO_FREE_VM; } - self.process - .virtual_allocations - .write() - .remove(&aligned_base); + split_virtual_allocation_around_released_region( + &self.process.virtual_allocations, + aligned_base, + aligned_len, + ); } if base_address.write_at_offset(0, aligned_base).is_none() || region_size.write_at_offset(0, aligned_len).is_none() @@ -1077,7 +1106,6 @@ fn free_region( virtual_allocations: &WindowsVirtualAllocations, base: usize, size: usize, - free_type: FreeType, ) -> Option<(usize, usize)> { if size == 0 { let allocation = virtual_allocations @@ -1088,15 +1116,54 @@ fn free_region( return Some((allocation.base, allocation.size)); } - if free_type == FreeType::MEM_RELEASE { - return None; - } - let (aligned_base, aligned_len) = page_aligned_region(base, size)?; find_private_virtual_allocation(virtual_allocations, aligned_base, aligned_len)?; Some((aligned_base, aligned_len)) } +fn split_virtual_allocation_around_released_region( + virtual_allocations: &WindowsVirtualAllocations, + released_base: usize, + released_size: usize, +) { + let Some(released_end) = released_base.checked_add(released_size) else { + return; + }; + let mut allocations = virtual_allocations.write(); + let Some((&allocation_key, allocation)) = allocations.range(..=released_base).next_back() + else { + return; + }; + let allocation = allocation.clone(); + let Some(allocation_end) = allocation.base.checked_add(allocation.size) else { + return; + }; + allocations.remove(&allocation_key); + + for (base, end) in [ + (allocation.base, released_base), + (released_end, allocation_end), + ] { + if base >= end { + continue; + } + let mut pages = RangeMap::new(); + for (range, protect) in allocation.pages.overlapping(base..end) { + pages.insert(range.start.max(base)..range.end.min(end), *protect); + } + allocations.insert( + base, + WindowsVirtualAllocation { + base, + size: end - base, + allocation_protect: allocation.allocation_protect, + type_: allocation.type_, + pages, + }, + ); + } +} + fn committed_pages( base: usize, size: usize, @@ -1778,6 +1845,27 @@ mod tests { info } + #[test] + fn page_targets_invalid_requires_executable_protection() { + let executable = + PageProtection::PAGE_EXECUTE_READWRITE | PageProtection::PAGE_TARGETS_INVALID; + assert_eq!( + parse_page_protection(executable.bits()), + Some(( + executable, + MemoryRegionPermissions::READ + | MemoryRegionPermissions::WRITE + | MemoryRegionPermissions::EXEC, + )) + ); + assert_eq!( + parse_page_protection( + (PageProtection::PAGE_READWRITE | PageProtection::PAGE_TARGETS_INVALID).bits() + ), + None + ); + } + #[test] fn read_virtual_memory_copies_across_chunks() { run_with_test_platform_pointers(|| { @@ -2237,6 +2325,90 @@ mod tests { }); } + #[test] + fn free_virtual_memory_partial_release_preserves_suffix_for_commit() { + run_with_test_platform_pointers(|| { + let task = crate::tests::test_task(); + let mut first_base = 0usize; + let mut first_size = 0x100000usize; + assert_eq!( + task.sys_nt_allocate_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut first_base), + 0, + mut_ptr(&mut first_size), + AllocationType::MEM_RESERVE.bits(), + PageProtection::PAGE_READWRITE.bits(), + ), + NtStatus::SUCCESS + ); + let mut second_base = 0usize; + let mut second_size = 28080usize; + assert_eq!( + task.sys_nt_allocate_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut second_base), + 0, + mut_ptr(&mut second_size), + AllocationType::MEM_RESERVE.bits(), + PageProtection::PAGE_READWRITE.bits(), + ), + NtStatus::SUCCESS + ); + let mut base = 0usize; + let mut region_size = 0x1d0000usize; + assert_eq!( + task.sys_nt_allocate_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut base), + 0, + mut_ptr(&mut region_size), + AllocationType::MEM_RESERVE.bits(), + PageProtection::PAGE_READWRITE.bits(), + ), + NtStatus::SUCCESS + ); + + let mut release_base = base; + let mut release_size = 0x1c0000usize; + assert_eq!( + task.sys_nt_free_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut release_base), + mut_ptr(&mut release_size), + FreeType::MEM_RELEASE.bits(), + ), + NtStatus::SUCCESS + ); + assert_eq!(release_base, base); + assert_eq!(release_size, 0x1c0000); + + let suffix_base = base + 0x1c0000; + let mut commit_base = suffix_base; + let mut commit_size = PAGE_SIZE * 2; + assert_eq!( + task.sys_nt_allocate_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut commit_base), + 0, + mut_ptr(&mut commit_size), + AllocationType::MEM_COMMIT.bits(), + PageProtection::PAGE_READWRITE.bits(), + ), + NtStatus::SUCCESS + ); + assert_eq!(commit_base, suffix_base); + assert_eq!(commit_size, PAGE_SIZE * 2); + let committed = MutPtr::::from_usize(commit_base); + assert_eq!(committed.write_at_offset(0, 0x5a), Some(())); + assert_eq!(committed.read_at_offset(0), Some(0x5a)); + + release_allocation(&task, first_base); + release_allocation(&task, second_base); + release_allocation(&task, suffix_base); + }); + } + #[test] fn free_virtual_memory_decommit_discards_page_contents() { run_with_test_platform_pointers(|| { From ec384b9bd6c7778ee931bd2d1df6966195fa4b73 Mon Sep 17 00:00:00 2001 From: Weiteng Chen Date: Wed, 26 Aug 2026 20:53:41 -0700 Subject: [PATCH 2/3] Fix Windows virtual memory edge cases --- litebox_shim_windows/src/syscalls/mm.rs | 203 ++++++++++++++++++- litebox_shim_windows/src/syscalls/section.rs | 57 +++++- 2 files changed, 254 insertions(+), 6 deletions(-) diff --git a/litebox_shim_windows/src/syscalls/mm.rs b/litebox_shim_windows/src/syscalls/mm.rs index 3305c9803..a90a09890 100644 --- a/litebox_shim_windows/src/syscalls/mm.rs +++ b/litebox_shim_windows/src/syscalls/mm.rs @@ -11,7 +11,7 @@ use litebox_common_windows::nt_status::NtStatus; use rangemap::RangeMap; use zerocopy::{FromBytes, Immutable, IntoBytes}; -use crate::syscalls::ProcessHandle; +use crate::syscalls::{ProcessHandle, section::pagefile_view_protection_is_compatible}; use crate::{ ConstPtr, MutPtr, PAGE_SIZE, ShimFS, ShimPlatform, Task, WindowsPageManager, WindowsVirtualAllocation, WindowsVirtualAllocations, @@ -53,6 +53,8 @@ impl PageProtection { let guard = self.contains(Self::PAGE_GUARD); let nocache = self.contains(Self::PAGE_NOCACHE); let writecombine = self.contains(Self::PAGE_WRITECOMBINE); + // TODO(windows-cfg): Enforce target invalidation for allocations and no-update semantics + // for protection changes; currently this operation flag is only validated. let targets_invalid = self.contains(Self::PAGE_TARGETS_INVALID); let executable = matches!( self.base(), @@ -489,6 +491,11 @@ impl Task { ) { return NtStatus::INVALID_PARAMETER; } + if allocation.type_ == MemoryType::MEM_MAPPED + && !pagefile_view_protection_is_compatible(allocation.allocation_protect, protect) + { + return NtStatus::SECTION_PROTECTION; + } if update_permissions( &self.global.page_manager, aligned_base, @@ -1108,9 +1115,10 @@ fn free_region( size: usize, ) -> Option<(usize, usize)> { if size == 0 { + let allocation_base = base & !(PAGE_SIZE - 1); let allocation = virtual_allocations .read() - .get(&base) + .get(&allocation_base) .filter(|allocation| allocation.type_ == MemoryType::MEM_PRIVATE) .cloned()?; return Some((allocation.base, allocation.size)); @@ -1299,7 +1307,7 @@ pub(super) fn parse_page_protection( ) -> Option<(PageProtection, MemoryRegionPermissions)> { let protect = PageProtection::from_bits(protect)?; let permissions = page_protect_to_permissions(protect)?; - Some((protect, permissions)) + Some((protect - PageProtection::PAGE_TARGETS_INVALID, permissions)) } fn page_protect_to_permissions(protect: PageProtection) -> Option { @@ -1846,13 +1854,13 @@ mod tests { } #[test] - fn page_targets_invalid_requires_executable_protection() { + fn page_targets_invalid_is_accepted_only_for_executable_protection() { let executable = PageProtection::PAGE_EXECUTE_READWRITE | PageProtection::PAGE_TARGETS_INVALID; assert_eq!( parse_page_protection(executable.bits()), Some(( - executable, + PageProtection::PAGE_EXECUTE_READWRITE, MemoryRegionPermissions::READ | MemoryRegionPermissions::WRITE | MemoryRegionPermissions::EXEC, @@ -1866,6 +1874,36 @@ mod tests { ); } + #[test] + fn page_targets_invalid_is_not_reported_as_page_protection() { + run_with_test_platform_pointers(|| { + let task = crate::tests::test_task(); + let mut base = 0usize; + let mut region_size = PAGE_SIZE; + assert_eq!( + task.sys_nt_allocate_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut base), + 0, + mut_ptr(&mut region_size), + (AllocationType::MEM_RESERVE | AllocationType::MEM_COMMIT).bits(), + (PageProtection::PAGE_EXECUTE_READ | PageProtection::PAGE_TARGETS_INVALID) + .bits(), + ), + NtStatus::SUCCESS + ); + + let info = query_basic_information(&task, base); + assert_eq!( + info.allocation_protect, + PageProtection::PAGE_EXECUTE_READ.bits() + ); + assert_eq!(info.protect, PageProtection::PAGE_EXECUTE_READ.bits()); + + release_allocation(&task, base); + }); + } + #[test] fn read_virtual_memory_copies_across_chunks() { run_with_test_platform_pointers(|| { @@ -2096,6 +2134,69 @@ mod tests { }); } + #[test] + fn commit_mapped_memory_rejects_protection_upgrade() { + run_with_test_platform_pointers(|| { + let task = crate::tests::test_task(); + let mut base = 0usize; + let mut region_size = PAGE_SIZE; + assert_eq!( + task.sys_nt_allocate_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut base), + 0, + mut_ptr(&mut region_size), + (AllocationType::MEM_RESERVE | AllocationType::MEM_COMMIT).bits(), + PageProtection::PAGE_READONLY.bits(), + ), + NtStatus::SUCCESS + ); + { + let mut allocations = task.process.virtual_allocations.write(); + let allocation = allocations.get_mut(&base).unwrap(); + allocation.type_ = MemoryType::MEM_MAPPED; + } + + let mut commit_base = base; + let mut commit_size = PAGE_SIZE; + assert_eq!( + task.sys_nt_allocate_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut commit_base), + 0, + mut_ptr(&mut commit_size), + AllocationType::MEM_COMMIT.bits(), + PageProtection::PAGE_READWRITE.bits(), + ), + NtStatus::SECTION_PROTECTION + ); + assert_eq!( + query_basic_information(&task, base).protect, + PageProtection::PAGE_READONLY.bits() + ); + + assert_eq!( + task.sys_nt_allocate_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut commit_base), + 0, + mut_ptr(&mut commit_size), + AllocationType::MEM_COMMIT.bits(), + PageProtection::PAGE_READONLY.bits(), + ), + NtStatus::SUCCESS + ); + + task.process + .virtual_allocations + .write() + .get_mut(&base) + .unwrap() + .type_ = MemoryType::MEM_PRIVATE; + release_allocation(&task, base); + }); + } + #[test] fn protect_virtual_memory_rounds_outputs_and_reports_old_protection() { run_with_test_platform_pointers(|| { @@ -2325,6 +2426,32 @@ mod tests { }); } + #[test] + fn free_virtual_memory_release_zero_size_rounds_address_to_allocation_base() { + run_with_test_platform_pointers(|| { + let task = crate::tests::test_task(); + let (base, allocation_size) = allocate_committed_rw(&task, PAGE_SIZE * 2); + + let mut release_base = base + 1; + let mut release_size = 0usize; + assert_eq!( + task.sys_nt_free_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut release_base), + mut_ptr(&mut release_size), + FreeType::MEM_RELEASE.bits(), + ), + NtStatus::SUCCESS + ); + assert_eq!(release_base, base); + assert_eq!(release_size, allocation_size); + assert_eq!( + query_basic_information(&task, base).state, + MemoryState::MEM_FREE.bits() + ); + }); + } + #[test] fn free_virtual_memory_partial_release_preserves_suffix_for_commit() { run_with_test_platform_pointers(|| { @@ -2409,6 +2536,72 @@ mod tests { }); } + #[test] + fn free_virtual_memory_middle_release_preserves_fragment_protections() { + run_with_test_platform_pointers(|| { + let task = crate::tests::test_task(); + let (base, _) = allocate_committed_rw(&task, PAGE_SIZE * 3); + + let mut prefix_base = base; + let mut prefix_size = PAGE_SIZE; + let mut old_protect = 0u32; + assert_eq!( + task.sys_nt_protect_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut prefix_base), + mut_ptr(&mut prefix_size), + PageProtection::PAGE_READONLY.bits(), + mut_ptr(&mut old_protect), + ), + NtStatus::SUCCESS + ); + + let suffix_base = base + PAGE_SIZE * 2; + let mut protect_suffix_base = suffix_base; + let mut suffix_size = PAGE_SIZE; + assert_eq!( + task.sys_nt_protect_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut protect_suffix_base), + mut_ptr(&mut suffix_size), + PageProtection::PAGE_EXECUTE_READ.bits(), + mut_ptr(&mut old_protect), + ), + NtStatus::SUCCESS + ); + + let mut release_base = base + PAGE_SIZE; + let mut release_size = PAGE_SIZE; + assert_eq!( + task.sys_nt_free_virtual_memory( + ProcessHandle::CURRENT, + mut_ptr(&mut release_base), + mut_ptr(&mut release_size), + FreeType::MEM_RELEASE.bits(), + ), + NtStatus::SUCCESS + ); + + let prefix = query_basic_information(&task, base); + assert_eq!(prefix.allocation_base, base); + assert_eq!(prefix.region_size, PAGE_SIZE); + assert_eq!(prefix.protect, PageProtection::PAGE_READONLY.bits()); + + let released = query_basic_information(&task, base + PAGE_SIZE); + assert_eq!(released.allocation_base, 0); + assert_eq!(released.region_size, PAGE_SIZE); + assert_eq!(released.state, MemoryState::MEM_FREE.bits()); + + let suffix = query_basic_information(&task, suffix_base); + assert_eq!(suffix.allocation_base, suffix_base); + assert_eq!(suffix.region_size, PAGE_SIZE); + assert_eq!(suffix.protect, PageProtection::PAGE_EXECUTE_READ.bits()); + + release_allocation(&task, base); + release_allocation(&task, suffix_base); + }); + } + #[test] fn free_virtual_memory_decommit_discards_page_contents() { run_with_test_platform_pointers(|| { diff --git a/litebox_shim_windows/src/syscalls/section.rs b/litebox_shim_windows/src/syscalls/section.rs index 3ba1037ab..98c626113 100644 --- a/litebox_shim_windows/src/syscalls/section.rs +++ b/litebox_shim_windows/src/syscalls/section.rs @@ -260,6 +260,9 @@ impl Task { if granted_access.is_empty() { return NtStatus::ACCESS_DENIED; } + if section_page_protection & PageProtection::PAGE_TARGETS_INVALID.bits() != 0 { + return NtStatus::INVALID_PAGE_PROTECTION; + } let Some((protection, _)) = parse_page_protection(section_page_protection) else { return NtStatus::INVALID_PAGE_PROTECTION; }; @@ -1077,7 +1080,7 @@ fn required_map_access(protection: PageProtection) -> SectionAccess { } } -fn pagefile_view_protection_is_compatible( +pub(super) fn pagefile_view_protection_is_compatible( section_protection: PageProtection, view_protection: PageProtection, ) -> bool { @@ -1328,6 +1331,58 @@ mod tests { (base, view_size) } + #[test] + fn section_apis_handle_page_targets_invalid_like_host() { + let task = test_task(); + let size = i64::try_from(PAGE_SIZE).unwrap(); + let cfg_protection = + PageProtection::PAGE_EXECUTE_READ | PageProtection::PAGE_TARGETS_INVALID; + let mut rejected_handle = Handle::default(); + assert_eq!( + task.sys_nt_create_section( + mut_ptr(&mut rejected_handle), + SectionAccess::ALL_ACCESS.bits(), + None, + Some(const_ptr(&size)), + cfg_protection.bits(), + SectionAllocationAttributes::SEC_COMMIT.bits(), + Handle::default(), + ), + NtStatus::INVALID_PAGE_PROTECTION + ); + + let handle = create_pagefile_section( + &task, + SectionAccess::ALL_ACCESS.bits(), + size, + PageProtection::PAGE_EXECUTE_READ, + ); + let mut base = 0usize; + let mut view_size = 0usize; + assert_eq!( + task.sys_nt_map_view_of_section(MapViewOfSectionParameters { + section_handle: handle, + process_handle: ProcessHandle::CURRENT, + base_address: mut_ptr(&mut base), + zero_bits: 0, + commit_size: 0, + section_offset: None, + view_size: mut_ptr(&mut view_size), + inherit_disposition: VIEW_SHARE, + allocation_type: 0, + page_protection: cfg_protection.bits(), + }), + NtStatus::SUCCESS + ); + assert_ne!(base, 0); + assert_eq!(view_size, PAGE_SIZE); + assert_eq!( + task.sys_nt_unmap_view_of_section(ProcessHandle::CURRENT, base), + NtStatus::SUCCESS + ); + task.close_section_handle(handle); + } + #[cfg(all(target_os = "windows", target_arch = "x86_64"))] fn host_kernel32_image() -> std::vec::Vec { let system_root = std::env::var_os("SystemRoot").expect("SystemRoot is set on Windows"); From ab27bcfb6cfc3d9675cda80cd5a8960fc4f32de9 Mon Sep 17 00:00:00 2001 From: Weiteng Chen Date: Wed, 26 Aug 2026 23:07:46 -0700 Subject: [PATCH 3/3] clean up code --- litebox_shim_windows/src/syscalls/mm.rs | 118 ------------------- litebox_shim_windows/src/syscalls/section.rs | 2 +- 2 files changed, 1 insertion(+), 119 deletions(-) diff --git a/litebox_shim_windows/src/syscalls/mm.rs b/litebox_shim_windows/src/syscalls/mm.rs index a90a09890..ca7fc9cb0 100644 --- a/litebox_shim_windows/src/syscalls/mm.rs +++ b/litebox_shim_windows/src/syscalls/mm.rs @@ -298,14 +298,6 @@ impl Task { let Some(size) = region_size.read_at_offset(0) else { return NtStatus::ACCESS_VIOLATION; }; - litebox_util_log::debug!( - base:% = format_args!("{base:#x}"), - size, - zero_bits:% = format_args!("{zero_bits:#x}"), - allocation_type:% = format_args!("{allocation_type:#x}"), - protect:% = format_args!("{protect:#x}"); - "NtAllocateVirtualMemory request" - ); if base_address.write_at_offset(0, base).is_none() || region_size.write_at_offset(0, size).is_none() { @@ -1853,27 +1845,6 @@ mod tests { info } - #[test] - fn page_targets_invalid_is_accepted_only_for_executable_protection() { - let executable = - PageProtection::PAGE_EXECUTE_READWRITE | PageProtection::PAGE_TARGETS_INVALID; - assert_eq!( - parse_page_protection(executable.bits()), - Some(( - PageProtection::PAGE_EXECUTE_READWRITE, - MemoryRegionPermissions::READ - | MemoryRegionPermissions::WRITE - | MemoryRegionPermissions::EXEC, - )) - ); - assert_eq!( - parse_page_protection( - (PageProtection::PAGE_READWRITE | PageProtection::PAGE_TARGETS_INVALID).bits() - ), - None - ); - } - #[test] fn page_targets_invalid_is_not_reported_as_page_protection() { run_with_test_platform_pointers(|| { @@ -2134,69 +2105,6 @@ mod tests { }); } - #[test] - fn commit_mapped_memory_rejects_protection_upgrade() { - run_with_test_platform_pointers(|| { - let task = crate::tests::test_task(); - let mut base = 0usize; - let mut region_size = PAGE_SIZE; - assert_eq!( - task.sys_nt_allocate_virtual_memory( - ProcessHandle::CURRENT, - mut_ptr(&mut base), - 0, - mut_ptr(&mut region_size), - (AllocationType::MEM_RESERVE | AllocationType::MEM_COMMIT).bits(), - PageProtection::PAGE_READONLY.bits(), - ), - NtStatus::SUCCESS - ); - { - let mut allocations = task.process.virtual_allocations.write(); - let allocation = allocations.get_mut(&base).unwrap(); - allocation.type_ = MemoryType::MEM_MAPPED; - } - - let mut commit_base = base; - let mut commit_size = PAGE_SIZE; - assert_eq!( - task.sys_nt_allocate_virtual_memory( - ProcessHandle::CURRENT, - mut_ptr(&mut commit_base), - 0, - mut_ptr(&mut commit_size), - AllocationType::MEM_COMMIT.bits(), - PageProtection::PAGE_READWRITE.bits(), - ), - NtStatus::SECTION_PROTECTION - ); - assert_eq!( - query_basic_information(&task, base).protect, - PageProtection::PAGE_READONLY.bits() - ); - - assert_eq!( - task.sys_nt_allocate_virtual_memory( - ProcessHandle::CURRENT, - mut_ptr(&mut commit_base), - 0, - mut_ptr(&mut commit_size), - AllocationType::MEM_COMMIT.bits(), - PageProtection::PAGE_READONLY.bits(), - ), - NtStatus::SUCCESS - ); - - task.process - .virtual_allocations - .write() - .get_mut(&base) - .unwrap() - .type_ = MemoryType::MEM_PRIVATE; - release_allocation(&task, base); - }); - } - #[test] fn protect_virtual_memory_rounds_outputs_and_reports_old_protection() { run_with_test_platform_pointers(|| { @@ -2426,32 +2334,6 @@ mod tests { }); } - #[test] - fn free_virtual_memory_release_zero_size_rounds_address_to_allocation_base() { - run_with_test_platform_pointers(|| { - let task = crate::tests::test_task(); - let (base, allocation_size) = allocate_committed_rw(&task, PAGE_SIZE * 2); - - let mut release_base = base + 1; - let mut release_size = 0usize; - assert_eq!( - task.sys_nt_free_virtual_memory( - ProcessHandle::CURRENT, - mut_ptr(&mut release_base), - mut_ptr(&mut release_size), - FreeType::MEM_RELEASE.bits(), - ), - NtStatus::SUCCESS - ); - assert_eq!(release_base, base); - assert_eq!(release_size, allocation_size); - assert_eq!( - query_basic_information(&task, base).state, - MemoryState::MEM_FREE.bits() - ); - }); - } - #[test] fn free_virtual_memory_partial_release_preserves_suffix_for_commit() { run_with_test_platform_pointers(|| { diff --git a/litebox_shim_windows/src/syscalls/section.rs b/litebox_shim_windows/src/syscalls/section.rs index 98c626113..798280645 100644 --- a/litebox_shim_windows/src/syscalls/section.rs +++ b/litebox_shim_windows/src/syscalls/section.rs @@ -1332,7 +1332,7 @@ mod tests { } #[test] - fn section_apis_handle_page_targets_invalid_like_host() { + fn section_apis_handle_page_targets_invalid() { let task = test_task(); let size = i64::try_from(PAGE_SIZE).unwrap(); let cfg_protection =