Skip to content

Commit 23c7057

Browse files
fix(agent): deduplicate exec audit events
1 parent 947167c commit 23c7057

4 files changed

Lines changed: 37 additions & 4 deletions

File tree

agent/crates/enterprise-utils/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,14 @@ pub mod ai_agent_enforcement {
548548
pub rule_index: u32,
549549
pub rule_id: String,
550550
pub mode: EnforcementMode,
551+
pub kernel_event_source: KernelEventSource,
552+
}
553+
554+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
555+
pub enum KernelEventSource {
556+
None,
557+
Lsm,
558+
KprobeOverride,
551559
}
552560

553561
#[derive(Clone, Debug, PartialEq, Eq)]

agent/src/config/handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6196,7 +6196,7 @@ mod tests {
61966196
);
61976197
assert_eq!(
61986198
config.ai_agent_enforcement.allowed_mechanisms,
6199-
vec!["lsm", "kprobe_override", "sigkill", "seccomp"]
6199+
vec!["lsm", "kprobe_override"]
62006200
);
62016201
assert!(config.ai_agent_enforcement.rules.is_empty());
62026202
}

agent/src/ebpf/test/test_ai_agent_source_contracts.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -402,8 +402,8 @@ def read_source(path: Path) -> str:
402402
"standalone exec override wrapper must define shared map symbols and include only exec override kprobes",
403403
)
404404
require(
405-
"buf->arg.bytes,\n\t\t\t\t AI_AGENT_EXEC_OVERRIDE_ARG_LEN" in exec_override_text,
406-
"AI Agent exec override must emit argv cmdline with the 64-byte argv buffer size, not the 256-byte path size",
405+
"buf->path,\n\t\t\t\t AI_AGENT_EXEC_PATTERN_LEN" in exec_override_text,
406+
"AI Agent exec override must report exec_path as cmdline placeholder instead of a partial argv slot",
407407
)
408408
syscall_override_bpf = ENTERPRISE_BPF / "ai_agent_syscall_override.bpf.c"
409409
require(

agent/src/ebpf_dispatcher.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ fn fill_ai_agent_root_pid(event: &mut BoxedProcEvents) {
192192
#[cfg(feature = "enterprise")]
193193
#[allow(static_mut_refs)]
194194
fn emit_ai_agent_enforcement_audit_event(event: &BoxedProcEvents) {
195-
use enterprise_utils::ai_agent_enforcement::EnforcementMode;
195+
use enterprise_utils::ai_agent_enforcement::{EnforcementMode, KernelEventSource};
196196

197197
if event.0.ai_agent_root_pid == 0 {
198198
return;
@@ -214,6 +214,17 @@ fn emit_ai_agent_enforcement_audit_event(event: &BoxedProcEvents) {
214214
if hit.mode != EnforcementMode::AuditOnly {
215215
return;
216216
}
217+
match hit.kernel_event_source {
218+
KernelEventSource::Lsm if AI_AGENT_EXEC_LSM_EVENTS_ACTIVE.load(Ordering::Relaxed) => {
219+
return;
220+
}
221+
KernelEventSource::KprobeOverride
222+
if AI_AGENT_EXEC_KPROBE_EVENTS_ACTIVE.load(Ordering::Relaxed) =>
223+
{
224+
return;
225+
}
226+
_ => {}
227+
}
217228
let Some(audit_event) = event
218229
.0
219230
.new_proc_block_event_for_audit(&hit.rule_id, policy.epoch)
@@ -690,6 +701,10 @@ static AI_AGENT_SYSCALL_RULES_MAP_FD: AtomicI32 = AtomicI32::new(-1);
690701
#[cfg(feature = "enterprise")]
691702
static AI_AGENT_POLICY_EPOCH_MAP_FD: AtomicI32 = AtomicI32::new(-1);
692703
#[cfg(feature = "enterprise")]
704+
static AI_AGENT_EXEC_LSM_EVENTS_ACTIVE: AtomicBool = AtomicBool::new(false);
705+
#[cfg(feature = "enterprise")]
706+
static AI_AGENT_EXEC_KPROBE_EVENTS_ACTIVE: AtomicBool = AtomicBool::new(false);
707+
#[cfg(feature = "enterprise")]
693708
const AI_AGENT_EXEC_RULES_BPF_MAX: usize = 256;
694709
#[cfg(feature = "enterprise")]
695710
const AI_AGENT_SYSCALL_RULES_BPF_MAX: usize = 32;
@@ -1716,6 +1731,8 @@ impl EbpfCollector {
17161731
let max_syscall_records = config.max_rules.min(AI_AGENT_SYSCALL_RULES_BPF_MAX);
17171732
if !config.enabled {
17181733
set_global_exec_policy(None);
1734+
AI_AGENT_EXEC_LSM_EVENTS_ACTIVE.store(false, Ordering::Relaxed);
1735+
AI_AGENT_EXEC_KPROBE_EVENTS_ACTIVE.store(false, Ordering::Relaxed);
17191736
Self::clear_ai_agent_exec_enforcement_bpf_maps(max_exec_records);
17201737
Self::clear_ai_agent_syscall_enforcement_bpf_maps(max_syscall_records);
17211738
return;
@@ -1750,6 +1767,8 @@ impl EbpfCollector {
17501767
Err(e) => {
17511768
warn!("AI Agent enforcement: failed to compile policy: {}", e);
17521769
set_global_exec_policy(None);
1770+
AI_AGENT_EXEC_LSM_EVENTS_ACTIVE.store(false, Ordering::Relaxed);
1771+
AI_AGENT_EXEC_KPROBE_EVENTS_ACTIVE.store(false, Ordering::Relaxed);
17531772
Self::clear_ai_agent_exec_enforcement_bpf_maps(max_exec_records);
17541773
return;
17551774
}
@@ -1775,10 +1794,16 @@ impl EbpfCollector {
17751794
set_global_exec_policy(None);
17761795
}
17771796
}
1797+
AI_AGENT_EXEC_LSM_EVENTS_ACTIVE.store(false, Ordering::Relaxed);
1798+
AI_AGENT_EXEC_KPROBE_EVENTS_ACTIVE.store(false, Ordering::Relaxed);
17781799
Self::clear_ai_agent_exec_enforcement_bpf_maps(max_exec_records);
17791800
return;
17801801
}
1802+
AI_AGENT_EXEC_LSM_EVENTS_ACTIVE.store(lsm_allowed, Ordering::Relaxed);
1803+
AI_AGENT_EXEC_KPROBE_EVENTS_ACTIVE.store(kprobe_override_allowed, Ordering::Relaxed);
17811804
} else {
1805+
AI_AGENT_EXEC_LSM_EVENTS_ACTIVE.store(false, Ordering::Relaxed);
1806+
AI_AGENT_EXEC_KPROBE_EVENTS_ACTIVE.store(false, Ordering::Relaxed);
17821807
Self::clear_ai_agent_exec_enforcement_bpf_maps(max_exec_records);
17831808
}
17841809

0 commit comments

Comments
 (0)