Fix two memory-safety defects in file-backed weights cache#20562
Fix two memory-safety defects in file-backed weights cache#20562JakeStevens wants to merge 1 commit into
Conversation
Summary: Fixes two defects in the XNNPACK file-backed packed-weight cache (`XNNWeightsCache`) 1. Use-after-munmap via `offset_to_addr` (SIGBUS). `offset_to_addr` returns the raw pointer stored in `packed_data_ptrs_[offset]`, which on the file-backed path is an address inside a `MAP_SHARED` region. `reset_for_fresh_write()` munmaps every region but left the offset->pointer slots populated, so a subsequent `offset_to_addr` handed XNNPACK a pointer into unmapped memory — dereferencing it faults (SIGBUS/SIGSEGV, or an ASAN report). Fix: null each file-backed slot before erasing its metadata entry, so `offset_to_addr` returns `nullptr` (the miss contract `look_up_or_insert` already expects) instead of a dangling pointer. 2. Mid-trailer-truncated cache file wrongly accepted. In `load_packed_cache`, the parse loop guard `i < entry_count && cursor + 4 <= end` terminated silently when fewer than 4 bytes remained, with no post-loop check that all `entry_count` entries were consumed. A file whose footer claimed `entry_count=N` but whose index region held only `N-1` complete entries (plus <4 trailing bytes) was accepted as a partial cache — the existing truncated-entry-header check only fires when >=4 bytes remain. The next `save_packed_index` would then rewrite a trailer covering only the partial subset, permanently dropping the missing entries (the exact failure the code's own comment warns about). Fix: after the loop, require that exactly `entry_count` entries were read and that the cursor consumed the whole index region; otherwise roll back (munmap, clear state) and return false, matching the in-loop corruption branches. A minimal test seam (`friend class XNNWeightsCacheTestPeer`) is added to the runtime header so the unit test can drive the private fresh-write path directly. Changes are mirrored across the `fbcode/` and `xplat/` copies. Differential Revision: D109886666
🔗 Helpful Links🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/20562
Note: Links to docs will display an error until the docs builds have been completed. ✅ No FailuresAs of commit fa23731 with merge base 825bd30 ( This comment was automatically generated by Dr. CI and updates every 15 minutes. |
|
@JakeStevens has exported this pull request. If you are a Meta employee, you can view the originating Diff in D109886666. |
This PR needs a
|
Summary:
Fixes two defects in the XNNPACK file-backed packed-weight cache (
XNNWeightsCache)Use-after-munmap via
offset_to_addr(SIGBUS).offset_to_addrreturns the raw pointer stored inpacked_data_ptrs_[offset], which on the file-backed path is an address inside aMAP_SHAREDregion.reset_for_fresh_write()munmaps every region but left the offset->pointer slots populated, so a subsequentoffset_to_addrhanded XNNPACK a pointer into unmapped memory — dereferencing it faults (SIGBUS/SIGSEGV, or an ASAN report). Fix: null each file-backed slot before erasing its metadata entry, sooffset_to_addrreturnsnullptr(the miss contractlook_up_or_insertalready expects) instead of a dangling pointer.Mid-trailer-truncated cache file wrongly accepted. In
load_packed_cache, the parse loop guardi < entry_count && cursor + 4 <= endterminated silently when fewer than 4 bytes remained, with no post-loop check that allentry_countentries were consumed. A file whose footer claimedentry_count=Nbut whose index region held onlyN-1complete entries (plus <4 trailing bytes) was accepted as a partial cache — the existing truncated-entry-header check only fires when >=4 bytes remain. The nextsave_packed_indexwould then rewrite a trailer covering only the partial subset, permanently dropping the missing entries (the exact failure the code's own comment warns about). Fix: after the loop, require that exactlyentry_countentries were read and that the cursor consumed the whole index region; otherwise roll back (munmap, clear state) and return false, matching the in-loop corruption branches.A minimal test seam (
friend class XNNWeightsCacheTestPeer) is added to the runtime header so the unit test can drive the private fresh-write path directly. Changes are mirrored across thefbcode/andxplat/copies.Differential Revision: D109886666