Skip to content

Commit 0f12807

Browse files
test: guard ai agent exec override size
1 parent 9c4b4f7 commit 0f12807

1 file changed

Lines changed: 72 additions & 0 deletions

File tree

agent/src/ebpf/test/test_ai_agent_source_contracts.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ def read_source(path: Path) -> str:
229229
if ENTERPRISE_AGENT.exists():
230230
exec_enforce_bpf = ENTERPRISE_BPF / "ai_agent_exec_enforce.bpf.c"
231231
exec_common_bpf = ENTERPRISE_BPF / "ai_agent_exec_common.bpf.h"
232+
enforcement_common_bpf = ENTERPRISE_BPF / "ai_agent_enforcement_common.bpf.h"
232233
require(
233234
exec_enforce_bpf.exists(),
234235
f"missing enterprise AI Agent exec enforcement BPF: {exec_enforce_bpf}",
@@ -237,8 +238,13 @@ def read_source(path: Path) -> str:
237238
exec_common_bpf.exists(),
238239
f"missing enterprise AI Agent exec common BPF header: {exec_common_bpf}",
239240
)
241+
require(
242+
enforcement_common_bpf.exists(),
243+
f"missing enterprise AI Agent enforcement common BPF header: {enforcement_common_bpf}",
244+
)
240245
exec_enforce_text = read_source(exec_enforce_bpf)
241246
exec_common_text = read_source(exec_common_bpf)
247+
enforcement_common_text = read_source(enforcement_common_bpf)
242248
support_text = read_source(ENTERPRISE_SUPPORT)
243249
feature_top_text = read_source(ENTERPRISE_FEATURE_TOP)
244250

@@ -287,6 +293,16 @@ def read_source(path: Path) -> str:
287293
and "ai_agent_exec_collect_path_facts" in exec_common_text,
288294
"AI Agent exec enforcement BPF must support suffix path matching with precomputed hashes",
289295
)
296+
path_facts_start = exec_common_text.find("ai_agent_exec_collect_path_facts(")
297+
path_facts_end = exec_common_text.find("ai_agent_hash_exec_path", path_facts_start)
298+
require(
299+
path_facts_start != -1 and path_facts_end != -1,
300+
"AI Agent exec BPF must keep path fact helper recognizable",
301+
)
302+
require(
303+
"#pragma unroll" not in exec_common_text[path_facts_start:path_facts_end],
304+
"AI Agent exec path fact collection must use a bounded loop, not a 256-byte unroll that bloats verifier processing",
305+
)
290306
require(
291307
"AI_AGENT_EXEC_CMDLINE_PREFIX_LEN" in exec_common_text
292308
and "cmdline_prefix_len" in exec_common_text
@@ -325,6 +341,11 @@ def read_source(path: Path) -> str:
325341
"ai_agent_submit_event" in exec_common_text,
326342
"AI Agent exec enforcement must submit events through the AI Agent pipeline",
327343
)
344+
require(
345+
"__builtin_memset(event, 0, sizeof(*event))" not in enforcement_common_text
346+
and "__builtin_memset(dst, 0, dst_sz)" not in enforcement_common_text,
347+
"AI Agent enforcement event helpers must avoid large BPF memset expansions that push kprobe override programs over the 4096-insn limit",
348+
)
328349
require(
329350
"cmdline_src_sz" in exec_common_text
330351
and "cmdline, cmdline_src_sz" in exec_common_text
@@ -401,6 +422,57 @@ def read_source(path: Path) -> str:
401422
and "cmdline_prefix_masks" in exec_override_text,
402423
"AI Agent exec override must match cmdline prefixes by fixed word masks",
403424
)
425+
cmdline_prefix_match_start = exec_override_text.find(
426+
"ai_agent_exec_override_cmdline_prefix_matches("
427+
)
428+
cmdline_prefix_match_end = exec_override_text.find(
429+
"ai_agent_exec_override_path_matches", cmdline_prefix_match_start
430+
)
431+
require(
432+
cmdline_prefix_match_start != -1 and cmdline_prefix_match_end != -1,
433+
"AI Agent exec override must keep cmdline prefix match helper recognizable",
434+
)
435+
cmdline_prefix_match_text = exec_override_text[
436+
cmdline_prefix_match_start:cmdline_prefix_match_end
437+
]
438+
require(
439+
"#pragma unroll" not in cmdline_prefix_match_text,
440+
"AI Agent exec override must not unroll 32-word cmdline prefix matching; it makes verifier state exceed the 1M processed-insn limit",
441+
)
442+
append_arg_start = exec_override_text.find(
443+
"ai_agent_exec_override_cmdline_append_arg("
444+
)
445+
read_argv_ptr_start = exec_override_text.find(
446+
"ai_agent_exec_override_read_argv_ptr", append_arg_start
447+
)
448+
build_cmdline_start = exec_override_text.find(
449+
"ai_agent_exec_override_build_cmdline("
450+
)
451+
read_argv_index_start = exec_override_text.find(
452+
"ai_agent_exec_override_read_argv_index", build_cmdline_start
453+
)
454+
require(
455+
append_arg_start != -1
456+
and read_argv_ptr_start != -1
457+
and build_cmdline_start != -1
458+
and read_argv_index_start != -1,
459+
"AI Agent exec override must keep cmdline build helpers recognizable",
460+
)
461+
cmdline_append_arg_text = exec_override_text[append_arg_start:read_argv_ptr_start]
462+
build_cmdline_text = exec_override_text[build_cmdline_start:read_argv_index_start]
463+
require(
464+
"#pragma unroll" not in cmdline_append_arg_text
465+
and "#pragma unroll" not in build_cmdline_text,
466+
"AI Agent exec override must not unroll argv cmdline construction; it makes kprobe override programs too large",
467+
)
468+
require(
469+
"ai_agent_exec_override_arg_reset" in exec_override_text
470+
and "__builtin_memset(buf, 0, sizeof(*buf))" not in exec_override_text
471+
and "__builtin_memset(buf->arg.bytes" not in exec_override_text
472+
and "__builtin_memset(buf->cmdline.bytes" not in exec_override_text
473+
and "__builtin_memset(buf->cmdline_arg.bytes" not in exec_override_text,
474+
"AI Agent exec override must avoid large scratch-buffer memset expansions; reset only fields that need deterministic contents",
475+
)
404476
require(
405477
"cmdline.bytes[buf->cmdline_len]" not in exec_override_text,
406478
"AI Agent exec override must not index cmdline with map-value cmdline_len directly; old verifiers reject the pointer arithmetic",

0 commit comments

Comments
 (0)