fix(yara-memory): classify macOS regions by their own VM entry - #683
Merged
Merged
Conversation
macOS memory scans misclassified two kinds of region, which made memory_scan_finds_marker_in_own_process flaky on the macOS runner and hid real heap memory from YARA. proc_regionfilename walks forward to the next file-backed entry, so an anonymous malloc region just below a mapping (for example between dyld's segments) took that file's name and was skipped as Mapped. Classify with PROC_PIDREGIONPATHINFO instead and check that the returned entry contains the address. The dyld shared cache was counted as private memory: its submaps and the slid __DATA/__LINKEDIT pieces between them have no path. Under the default 64 MB budget it used about 40 MB before the scan reached the malloc regions above it, so no allocation of 16 KB or more was ever scanned. Treat contiguous runs bounded by submap entries as library memory (Image or Mapped), matching Linux and Windows.
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.
Summary
Fixes the flaky
Tests (macOS)failure inmemory_scan_finds_marker_in_own_process(run 36885026801). The test started running on macOS when #674 un-ignored it. The flake came from two real detection bugs in the macOS memory reader (src/memory/macos.rs).1. Anonymous memory took the name of the next file mapping
proc_regionfilename(XNUPROC_PIDREGIONPATH) walks forward from the address to the next file-backed entry and returns that path. A malloc region sitting between dyld's segments was reported as/usr/lib/dyld, classifiedMapped, and skipped. When the test's marker landed there, the scan missed it (about 1 in 20 runs locally).The fix classifies with
PROC_PIDREGIONPATHINFO, throughlibproc::proc_pid::pidinfowith a#[repr(C)]struct. Its layout was checked against the SDK headers on arm64 and x86_64 (1272 bytes), and a compile-time assert pins the size. A path is only accepted when the returned entry actually contains the address.2. The dyld shared cache used up the scan budget as "private" memory
The shared cache's submaps and the slid
__DATA/__LINKEDITpieces between them have no backing path, so they counted as private. Under the default 64 MB budget the scan spent about 40 MB there and stopped around0x1fb744000. It never reached the malloc regions above the cache (Malloc Smallat0x7b8b000000on macOS 27). Measured on arm64 with default settings:Total private memory read dropped from 64 MB (budget exhausted) to 47 MB (whole process covered).
The fix: entries in a contiguous run that starts and ends with a
PROC_REGION_SUBMAPentry are treated as shared-cache library memory. They are classifiedImageif executable, otherwiseMapped, matching Linux file-backed segments and WindowsMEM_IMAGE. An address gap ends a run, so heaps between two separate shared regions are never swallowed. The config reference anddocs/configuration.mdnote the macOS behavior.Test plan
anonymous_region_below_a_file_mapping_has_no_filename: fails on the oldregionfilenamelookup, passes now.shared_cache_spans_contiguous_runs_between_submaps(synthetic runs, gaps, trailing pieces) andown_shared_cache_is_found_and_excludes_the_heap(live process).cargo test --test yara_memory: 0 failures in 200 runs locally, against about 1 in 20 before.cargo clippy --locked --all-targets -- -D clippy::all,cargo fmt --check, and the fullcargo test --lockedpass on macOS arm64.memory_scan_finds_marker_in_child_process(ignored) not verified: it needs root fortask_for_pidon another process.