Skip to content

fix: synchronize DeclareIntent authorization commit per PID#106

Merged
nevinshine merged 1 commit into
nevinshine:mainfrom
kashyapanand21:fix/pid-lock-declareintent-race
Jun 1, 2026
Merged

fix: synchronize DeclareIntent authorization commit per PID#106
nevinshine merged 1 commit into
nevinshine:mainfrom
kashyapanand21:fix/pid-lock-declareintent-race

Conversation

@kashyapanand21

Copy link
Copy Markdown
Contributor

Description

Fixes #104

This PR fixes a TOCTOU race condition in DeclareIntent where kernel taint state could change while verifier.verify() was running, allowing stale authorization state to commit execution policy updates afterward.

Root Cause

DeclareIntent previously followed this flow:

  • read taint state
  • run blocking verification
  • commit exec policy updates

Because the Cortex gRPC server is multi-threaded, taint state could escalate during the verification window. The final exec-policy commit was not synchronized with the taint re-check.

Fix

This PR introduces:

  • per-PID synchronization using threading.Lock
  • a final taint re-check inside the PID-scoped lock
  • atomic exec policy commit (send_update_exec) under the same lock
  • fail-closed behavior if the final taint verification fails
  • regression coverage for taint escalation during verification

The expensive verify() phase intentionally remains outside the lock to avoid unnecessary contention and preserve concurrency.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)

Testing

Verified locally with:

py -m py_compile cortex/main.py

py -m pytest cortex/test_control_security.py -v
py -m pytest cortex/test_intent_redeclare_taint.py -v
py -m pytest cortex/test_guardian_thread_safety.py -v

Added a regression test covering taint escalation during verification.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • My changes generate no new warnings
  • I have checked my code and corrected any misspellings

@nevinshine

Copy link
Copy Markdown
Owner

Could you do a quick pass to remove the redundant send_update_exec calls and duplicate lines from the lower half of the function? Once that is cleaned up, this is a definite merge!

@kashyapanand21

kashyapanand21 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

@nevinshine

Thanks for the review!
I did a full pass and traced the current send_update_exec call sites:

  • Line 279 — early taint deny, before verify()
  • Line 292 — rate-limit penalty, before verify()
  • Line 355 — taint escalated during verification, inside pid_lock
  • Line 368 — fail-closed path if the final taint re-check fails
  • Line 379 — allowlist commit inside the atomic commit section
  • Line 383 — deny-path exec-policy commit inside the atomic commit section

From my review, each call appears to serve a distinct purpose in either an early-exit path or the PID-locked commit section, and all tests (including the new TOCTOU regression test) are passing.

That said, I may be looking at a different section than the one you had in mind. Could you point me to the specific redundant send_update_exec calls or duplicate lines you'd like cleaned up? I want to make sure I preserve the intended security behavior while simplifying the implementation.

@nevinshine nevinshine merged commit c220b1c into nevinshine:main Jun 1, 2026
4 checks passed
@nevinshine

Copy link
Copy Markdown
Owner

I was reviewing the raw diff output and got completely tripped up by the text formatting. The "duplicate" lines I was looking at were actually just the diff's deletion markers that had lost their syntax highlighting in my terminal, making it look like the lines were duplicated.

Your review is correct. You flawlessly migrated the send_update_exec calls into the atomic lock section and cleaned up the old paths. The implementation is rock solid.

Sorry for the confusion,

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Security] TOCTOU race in DeclareIntent allows concurrent requests to bypass taint synchronization and receive exec allowlists

2 participants