Skip to content

fix(hy-check): enforce freeze and loan windows across defer and call-arg moves (fixes #98) - #513

Closed
gelismarvel wants to merge 1 commit into
limitlessprojects:mainfrom
gelismarvel:fix/issue-98-real-patch
Closed

gelismarvel wants to merge 1 commit into
limitlessprojects:mainfrom
gelismarvel:fix/issue-98-real-patch

Conversation

@gelismarvel

Copy link
Copy Markdown
Contributor

Summary

Fixes #98

Closes the Stmt::Defer and call-argument move soundness bypasses where deferred calls and move arguments in ordinary calls escaped A1b/A7 freeze and A2/A3 loan windows (HYB-E3003, HYB-E3004, HYB-E3101, HYB-E3102):

  1. Stmt::Defer execution-at-exit freeze (freeze.rs, model.rs, loans.rs, lib.rs, closures.rs):
    • Record live binding uses inside Stmt::Defer { call, .. } in FnState::deferred_uses paired with their (scope_depth, name) connected storage group (scoped_binding_group via storage_component).
    • When any subsequent move or consuming API call (mark_move) transfers ownership of a binding in that storage group before function exit, emit HYB-E3003 (A1b / A7) for the deferred use that will execute at function exit after the transfer.
    • Preserve deferred-use group connectivity across local defines and non-self rebinds (transfer_deferred_uses_before_sever).
  2. Stmt::Defer loan window extension (walk.rs, loans.rs, lib.rs):
    • Extend last_use of bindings referenced in Stmt::Defer to fn_end (flatten_with_results) and pass Some(fn_end) as loop_end when processing calls inside Stmt::Defer, so handle borrow loans (A2 / A7) and &m[k] map-slot loans (A3) inside defer remain live until function exit.
  3. Call-argument move transfers (lib.rs, freeze.rs, loans.rs):
    • Process move operands inside call arguments and Stmt::Defer via process_expr_moves / process_defer_moves so eat(move m) and m2 := id(move m) freeze m (HYB-E3003), validate non-owned moves (HYB-E3004), and propagate non_owned_origin.

Verification

  • Added 6 unit tests in compiler/crates/hy-check/src/lib.rs (defer_use_before_move_rejects_a1b_e3003, defer_alias_use_before_move_rejects_a1b_e3003, defer_use_before_consume_rejects_a7_e3003, defer_extends_map_slot_and_handle_borrow_loans_to_fn_exit, defer_move_freezes_binding_and_validates_non_owned, call_arg_move_freezes_binding_and_propagates_non_owned).
  • cargo test --manifest-path compiler/Cargo.toml -p hy-check passes (143/143 unit tests + all integration tests, 0 warnings).

@gelismarvel

Copy link
Copy Markdown
Contributor Author

Closing this PR. On review, its changes substantially duplicate the earlier PR #99 by @sonson0910, so it should not have been submitted as separate work. Withdrawing it (and any bounty claim attached to it) in favor of the original. Apologies for the noise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[soundness] Stmt::Defer and call-arg moves bypass A1b/A7 freeze and A2/A3 loan windows (data race at function exit)

1 participant