vyre_libs/security/
taint_kill.rs1use vyre_foundation::ir::Program;
19use vyre_primitives::bitset::and_not::bitset_and_not;
20use vyre_primitives::graph::csr_forward_traverse::bitset_words;
21
22pub(crate) const OP_ID: &str = "vyre-libs::security::taint_kill";
23
24#[must_use]
31pub fn taint_kill(
32 node_count: u32,
33 frontier_in: &str,
34 kill_set: &str,
35 frontier_out: &str,
36) -> Program {
37 let words = bitset_words(node_count);
38 let primitive = bitset_and_not(frontier_in, kill_set, frontier_out, words);
39 Program::wrapped(
40 primitive.buffers().to_vec(),
41 primitive.workgroup_size(),
42 crate::region::reparent_program_children(&primitive, OP_ID),
43 )
44}
45
46#[must_use]
48#[cfg(test)]
49pub(crate) fn cpu_ref(frontier_in: &[u32], kill_set: &[u32]) -> Vec<u32> {
50 vyre_primitives::bitset::and_not::cpu_ref(frontier_in, kill_set)
51}
52
53pub struct TaintKill;
55
56impl vyre_spec::soundness::SoundnessTagged for TaintKill {
57 fn soundness(&self) -> vyre_spec::soundness::Soundness {
58 vyre_spec::soundness::Soundness::Exact
59 }
60}
61
62#[cfg(test)]
63mod tests {
64 use super::*;
65
66 #[test]
67 fn empty_kill_set_passes_frontier_through() {
68 assert_eq!(cpu_ref(&[0xFFFF_FFFF], &[0]), vec![0xFFFF_FFFF]);
69 }
70
71 #[test]
72 fn full_kill_set_zeros_frontier() {
73 assert_eq!(cpu_ref(&[0xFFFF_FFFF], &[0xFFFF_FFFF]), vec![0]);
74 }
75
76 #[test]
77 fn partial_kill_set_drops_specific_bits() {
78 let frontier = [0x0000_FFFFu32];
81 let kill = [0x0000_FF00u32];
82 assert_eq!(cpu_ref(&frontier, &kill), vec![0x0000_00FF]);
83 }
84
85 #[test]
86 fn idempotent_under_repeated_application() {
87 let frontier = [0xDEAD_BEEFu32];
88 let kill = [0xF0F0_F0F0u32];
89 let after_one = cpu_ref(&frontier, &kill);
90 let after_two = cpu_ref(&after_one, &kill);
91 assert_eq!(after_one, after_two);
92 }
93
94 #[test]
95 fn taint_kill_program_emits_and_not_region() {
96 let program = taint_kill(64, "fin", "kill", "fout");
97 let buffer_names: Vec<&str> = program.buffers().iter().map(|b| b.name()).collect();
98 assert!(buffer_names.contains(&"fin"));
99 assert!(buffer_names.contains(&"kill"));
100 assert!(buffer_names.contains(&"fout"));
101 }
102}