Repository navigation
File DLP copy correlation, part 3: process taint (#334) - #378
Merged
Merged
Conversation
process_taint (Linux, off by default): a file written to a monitored drive
that can't be judged on its own (unreadable, or an archive) is judged by
the files its writer read just before.
- A second fanotify group gets FAN_OPEN notifications for the mount holding
the home folders, only while taint is on and a destination is watched; it
is opened the first time it's needed. Its own reader means a flood of
opens can only overflow its queue, never the destination events.
- Each open under /home costs a readlink and an fstat; the path and
identity go into an in-memory store (32 per process, 4096 processes,
taint_window_seconds). Nothing is scanned at open time.
- At a destination event that matched nothing and couldn't be judged on its
own, up to 8 sources (newest first, opened after the process started, so
a reused pid inherits nothing) are reopened with O_NOFOLLOW, checked to
be the same file, and scanned through the cache. A match replaces the
fail-mode events with correlated ones (correlation {method: taint,
source_sha256, source_name}, verdict_source correlation), and the
after-write action applies. A readable file that matched nothing is never
judged by its writer's earlier reads.
- capabilities.copy_correlation.process_taint: supported on Linux. Health
reports processes tracked and open events lost to overflow.
- Measured (privileged container, 100,000 opens while a drive is mounted):
the workload took 1.05 s instead of 0.83 s (~28%), the agent used ~5 us
of CPU per open, no events were lost.
- CI's root step must also run TestEnforcer_TaintEndToEnd.
Refs #334
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
neamul602
enabled auto-merge
November 2, 2026 11:46
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the
|
Windows can't rename a file that is open, so the test's destination file was never there and the fake scanner got nil. Write it under its final name, then open it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
This was referenced Nov 2, 2026
Merged
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.



Part 3 of 3 for #334 (parts 1 and 2: #376, #377), following the merged backend contract (BrainStation-23/Compliance-OS#572):
process_taint. Linux; off by default.What it does
A file written to a monitored drive that can't be judged on its own (unreadable, for example a password-protected archive built straight onto the stick; or an archive) is judged by the files its writer read just before.
FAN_OPENnotifications for the mount holding/home, only while taint is on and a drive or share is watched. It's opened the first time it's needed. It has its own reader, so a flood of opens (a build,npm install) can only overflow its own queue, never the drive's write events./homecosts a readlink and an fstat. The path and identity go into an in-memory store: 32 per process, 4096 processes, fortaint_window_seconds. Nothing is scanned at open time.O_NOFOLLOW, checked to be the same file (device and inode), and scanned through the cache like any file;correlation: {method: taint, source_sha256, source_name},verdict_source: correlation), and the after-write action (File DLP copy correlation, part 1: settings, after-write action, capabilities (#334) #376) applies to the written file.capabilities.copy_correlation.process_taintissupportedon Linux. Health reports processes tracked and open events lost to overflow.Measured cost
In a privileged container: 100,000 file opens while a drive was mounted and taint was on.
So open-heavy work runs about 28% slower while a drive is mounted with taint on. That's why it's off by default and only active while a destination is mounted. A later improvement could use
FAN_REPORT_FIDto avoid a file descriptor per event.Test plan
monitorpolicy records without touching the file.TestEnforcer_TaintEndToEnd, added to CI's must-run list): a shell reads a secret file and writes a binary blob to the tmpfs stick, giving a correlated event withplan.txtas the source. Another process writing the same blob gives no event.make verify-crossand the changelog check pass.Refs #334
🤖 Generated with Claude Code