host/taint: honour the ownership carriers on producers only
Neither ownership carrier is a security boundary — both are strings any unprivileged process can put on its own node — so an unrestricted taint root is a denial of the whole feature. An unlinked Stream/Input/Audio named `peerspeak_owned_rogue` is a tainted *reader* (receivers includes nodes by role, no link required) and an unbounded one, so propagate_unresolved_owner fails every candidate on the machine closed. Measured before this change: BASELINE eligible=1 excluded=[] became WITH IMPOSTOR eligible=0 excluded=[firefox -> unresolved-owner]. Restricting the root to Stream/Output/Audio costs nothing real — peerspeak only ever tags playback streams — and the AEC's virtual sink/source is untouched, since it roots on module id, not on this tag. A tag that is ignored is not silent: misplaced_ownership_tags feeds a new `ignored_ownership_tags` audit field (omitted when empty), because the fix *removes* an exclusion, and the two causes of a dropped tag — a peerspeak tagging bug, or an impersonation attempt — both want seeing. Codex phase-1 review F2, reproduced live. Round 10, R10-1. 5 new rows, mutation-verified: dropping the role restriction kills both engine rows, and stubbing the diagnostic kills the third. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -161,6 +161,16 @@ impl Graph {
|
||||
self.node(&name, MediaRole::StreamOutput, peerspeak_owned(client, pid))
|
||||
}
|
||||
|
||||
/// Both ownership carriers on a node of **any** role — an impostor, or a
|
||||
/// producer-side tagging bug. Only [`MediaRole::StreamOutput`] makes it a
|
||||
/// taint root (round 10, R10-1); every other role must be ignored, and
|
||||
/// these are the fixtures that prove it.
|
||||
pub fn peerspeak_tagged_node(&mut self, name: &str, role: MediaRole, pid: u32) -> NodeRef {
|
||||
let client = self.client_of_app(pid);
|
||||
let name = format!("{}{name}_{pid}", super::PEERSPEAK_OWNED_NODE_PREFIX);
|
||||
self.node(&name, role, peerspeak_owned(client, pid))
|
||||
}
|
||||
|
||||
/// Carrier 1 alone: the `peerspeak.owned` property present, the
|
||||
/// `node.name` prefix absent. What the engine sees for a node it had to
|
||||
/// bind to observe (v3.5 §6.7).
|
||||
|
||||
Reference in New Issue
Block a user