Skip to content

Use access events in MemOutOfBounds analysis#2027

Open
karoliineh wants to merge 15 commits into
masterfrom
oob-event
Open

Use access events in MemOutOfBounds analysis#2027
karoliineh wants to merge 15 commits into
masterfrom
oob-event

Conversation

@karoliineh
Copy link
Copy Markdown
Member

This PR refactors memOutOfBounds to use access events, similarly to the useAfterFree refactoring in #1864.

Instead of recursively traversing expressions inside memOutOfBounds to rediscover what is accessed, the analysis now consumes Events.Access emitted by accessAnalysis. This makes the analysis depend on the shared access infrastructure and removes the local implicit/explicit dereference traversal logic. It also refactors and simplifies the code in other aspects.

This PR replaces #2024. The stored-pointer-offset dereference fix (#2017 (comment)) from #2024 is included here as part of the event-based cleanup instead of being merged separately.

Changes:

  • Register memOutOfBounds as depending on access.
  • Enable single-threaded access event emission when memOutOfBounds is active.
  • Replace expression/lvalue traversal in memOutOfBounds with handling of Events.Access.
  • Split OOB checks into clearer cases:
    • pointer dereference checks
    • pointer value checks
    • counted library accesses such as memset/memcpy (kept close to as was originally)
  • Account for stored pointer offsets when checking dereference accesses.
  • Clean up diagnostic reporting through a shared OOB reporting helper.
  • Update dune test outputs for changed diagnostic wording.

I ran the portfolio on 074e4d7 for memsafety tasks with 15s timeouts (as there were only 5 tasks that took > 12s to solve in the C.MemSafety category from SV-COMP 2026). The results were sound.

Open questions

  1. Check whether access-event address information can be used more directly in dereference checks without double-counting offsets.
  2. Figure out if and why the check_ptr_value_access case is even needed to get rid of the lt and le things (Fix memOutOfBounds handling of negative pointer offsets #2017 (comment))
  3. Investigate whether the local offset conversion can be replaced by PreValueDomain.Offs.to_index without losing precision. Currently, the index case is less precise in the version Offsets.to_index and using this, some OOB tests start to fail due to lack of precision, but adding a case of
| Some typ -> (None, idx_of_int (Cilfacade.bytesSizeOf typ))

in between the

| Some TArray(item_typ, _, _) -> ...
| _ -> (None, Idx.top ())

makes some other (unrelated) tests fail

I also didn't resolve the TODOs that were already there about deduplicating some functions with base, namely:

  • get_size_of_ptr_target (* TODO: deduplicate with base *)
  • convert_offset (* TODO: Some duplication with convert_offset in base.ml, unclear how to immediately get more reuse *)

karoliineh and others added 15 commits May 7, 2026 15:21
Co-authored-by: Michael Schwarz <michael.schwarz93@gmail.com>
Use access events instead of recursively traversing expressions in memOutOfBounds.

This follows the same direction as the useAfterFree refactoring #1864: accessAnalysis determines what is accessed, while memOutOfBounds only checks the reported access. This avoids duplicating access traversal logic and removes the need to distinguish implicit from explicit dereferences in the analysis itself.

Keep the initial refactor close to the previous implementation to make the behavioral diff easier to review. Further cleanup of now-obsolete helpers is left for a follow-up commit.
Co-authored-by: Simmo Saan <simmo.saan@gmail.com>
@karoliineh karoliineh self-assigned this May 8, 2026
@karoliineh karoliineh added cleanup Refactoring, clean-up bug unsound sv-comp SV-COMP (analyses, results), witnesses labels May 8, 2026
@karoliineh karoliineh requested a review from sim642 May 8, 2026 10:53
@karoliineh karoliineh added this to the SV-COMP 2027 milestone May 8, 2026
@sim642 sim642 assigned sim642 and unassigned karoliineh May 8, 2026
@michael-schwarz michael-schwarz requested a review from Copilot May 9, 2026 14:48
collect_local := get_bool "witness.yaml.enabled" && get_bool "witness.invariant.accessed";
let activated = get_string_list "ana.activated" in
emit_single_threaded := List.mem (ModifiedSinceSetjmp.Spec.name ()) activated || List.mem (PoisonVariables.Spec.name ()) activated || List.mem (UseAfterFree.Spec.name ()) activated (* TODO: some of these don't have access as dependency *)
emit_single_threaded := List.mem (ModifiedSinceSetjmp.Spec.name ()) activated || List.mem (PoisonVariables.Spec.name ()) activated || List.mem (UseAfterFree.Spec.name ()) activated || List.mem (MemOutOfBounds.Spec.name ()) activated (* TODO: some of these don't have access as dependency *)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do this TODO here? Seems simple.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the memOutOfBounds analysis to consume shared Events.Access emitted by accessAnalysis instead of locally traversing expressions/lvalues, aligning it with the access-event-based infrastructure used by other analyses (e.g., useAfterFree).

Changes:

  • Register memOutOfBounds as depending on access and add an event handler to process Events.Access.
  • Rework OOB checking logic into clearer cases (deref checks, pointer-value checks, counted library accesses) and add stored-pointer-offset handling for dereferences.
  • Update regression tests/expected outputs for changed diagnostics and add a one-past-pointer dereference regression.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
src/analyses/memOutOfBounds.ml Main refactor: switch to access events, new OOB reporting helper, new offset handling and event-based checking logic.
src/analyses/accessAnalysis.ml Enable single-threaded access event emission when memOutOfBounds is activated.
tests/regression/74-invalid_deref/36-one-past-pointer.c Add explicit one-past dereference to ensure a warning is produced.
tests/regression/74-invalid_deref/01-oob-heap-simple.t Update expected warning text to match refactored diagnostics.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

| _ -> ()
(* Actual dereference/access through a pointer. *)
| AddrOf (Mem e, o) when not (ptr_only_has_str_addr e) ->
check_ptr_deref_access man e o
Comment on lines +269 to +271
(* Pointer arithmetic / pointer value access. *)
| _ when isPointerType (typeOf exp) && not (ptr_only_has_str_addr exp) ->
check_ptr_value_access man exp (get_addr_offs_from_ad man exp ad)
Comment on lines +315 to +317
| AddrOf lval
| StartOf lval ->
let ptr_exp = Lval lval in
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug cleanup Refactoring, clean-up sv-comp SV-COMP (analyses, results), witnesses unsound

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants