@@ -229,6 +229,7 @@ def read_source(path: Path) -> str:
229229if 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