fix(vfs): harden getdirentries and APR filepath resolution#77
Open
MikeSaito wants to merge 2 commits into
Open
fix(vfs): harden getdirentries and APR filepath resolution#77MikeSaito wants to merge 2 commits into
MikeSaito wants to merge 2 commits into
Conversation
Follow-up VFS hardening task applying the same guest-writes-first discipline established in the time subsystem to directory enumeration.
Deferred Commit in KernelGetdirentriesCore:
- Reordered guest output so the 512-byte dirent buffer is written first via TryWriteCompat, basep is updated second (when non-null) via TryWriteUInt64Compat, and directory.NextIndex is advanced only after both guest writes succeed.
- Removed the early basep write at method entry that could mutate guest memory before buffer validation and advance the host cursor before a successful dirent delivery, causing permanent entry loss on MEMORY_FAULT at bufferAddress.
- EOF handling: when currentIndex >= Entries.Length, write basep with the final offset and return 0 without mutating NextIndex, matching FreeBSD getdirentries(2) semantics and preventing infinite retry loops.
KernelGetdents path: basePointerAddress is passed as 0, so the transaction collapses to buffer write then host cursor advance with no basep side effect.
Out of scope: coalesced {id, size} writes in sceKernelAprResolveFilepathsToIdsAndFileSizes; NetCtl connected-state stubs.
Files: KernelMemoryCompatExports.cs
Refactored sceKernelAprResolveFilepathsToIdsAndFileSizes to stop writing ids and sizes into guest memory one element at a time. - Removed the uint.MaxValue placeholder write at the start of each loop iteration. - Path resolution and file size lookup now fill host-side buffers first; on EFAULT or NOT_FOUND the guest ids/sizes arrays are left untouched. - ids and sizes are packed into contiguous byte buffers and written with one TryWriteCompat call per output array instead of separate TryWriteUInt32Compat / TryWriteUInt64Compat per index. - AmprFileRegistry.Register is called only after guest writes succeed. - AmprFileRegistry.ComputeFileId is internal so ids can be computed without registering paths during the resolve loop. Files: KernelMemoryCompatExports.cs, AmprFileRegistry.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up VFS hardening applying the same guest-writes-first discipline from the time subsystem to directory enumeration and APR filepath resolution.
Getdirentries (
KernelGetdirentriesCore):TryWriteCompat, updatebasepsecond (when non-null) viaTryWriteUInt64Compat, and advancedirectory.NextIndexonly after both guest writes succeed.basepwrite at method entry that could mutate guest memory before buffer validation and advance the host cursor before a successful dirent delivery, causing permanent entry loss onMEMORY_FAULTatbufferAddress.currentIndex >= Entries.Length), writebasepwith the final offset and return 0 without mutatingNextIndex, matching FreeBSDgetdirentries(2)semantics. ForKernelGetdents,basePointerAddressis 0, so only the buffer write and host cursor advance run.APR (
sceKernelAprResolveFilepathsToIdsAndFileSizes):EFAULTorNOT_FOUND, guest arrays are untouched andAmprFileRegistryis not updated.localSizesandlocalIdsinto contiguous byte buffers and write each output array with oneTryWriteCompatcall instead of per-elementTryWriteUInt32Compat/TryWriteUInt64Compatpairs.AmprFileRegistry.Registerruns only after guest writes succeed.AmprFileRegistry.ComputeFileIdis internal so ids can be computed during the resolve loop without premature registry mutation. Removed theuint.MaxValueplaceholder pre-write.Out of scope: NetCtl connected-state stubs; writable range validation pre-probes for split outputs.
Files:
KernelMemoryCompatExports.cs,AmprFileRegistry.cs