@@ -299,9 +299,14 @@ def read_source(path: Path) -> str:
299299 path_facts_start != - 1 and path_facts_end != - 1 ,
300300 "AI Agent exec BPF must keep path fact helper recognizable" ,
301301 )
302+ path_facts_text = exec_common_text [path_facts_start :path_facts_end ]
302303 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" ,
304+ re .search (r"#define\s+AI_AGENT_EXEC_PATTERN_SCAN_LEN\s+64" , exec_common_text )
305+ and "#ifdef AI_AGENT_EXEC_UNROLL_PATH_FACTS" in path_facts_text
306+ and "#pragma unroll" in path_facts_text
307+ and "for (__u32 i = 0; i < AI_AGENT_EXEC_PATTERN_SCAN_LEN; i++)" in path_facts_text
308+ and "if (!ended || len == 0)" in path_facts_text ,
309+ "AI Agent exec path fact collection must scan a verifier-friendly 64-byte prefix and only unroll in small enforcement objects" ,
305310 )
306311 require (
307312 "AI_AGENT_EXEC_CMDLINE_PREFIX_LEN" in exec_common_text
@@ -332,6 +337,10 @@ def read_source(path: Path) -> str:
332337 and "argv_pattern_hash" not in lsm_body ,
333338 "AI Agent exec LSM hook must ignore argv/cmdline-qualified rules to avoid path-only false positives" ,
334339 )
340+ require (
341+ "#define AI_AGENT_EXEC_UNROLL_PATH_FACTS" in exec_enforce_text ,
342+ "AI Agent exec LSM hook must unroll the 64-byte path fact helper to avoid bounded-loop verifier state explosion" ,
343+ )
335344 require (
336345 "pattern_hash" in exec_common_text
337346 and "ai_agent_hash_exec_path" in exec_common_text ,
@@ -389,11 +398,18 @@ def read_source(path: Path) -> str:
389398 )
390399 require (
391400 re .search (r"#define\s+AI_AGENT_EXEC_OVERRIDE_ARG_LEN\s+64" , exec_override_text )
401+ and re .search (r"#define\s+AI_AGENT_EXEC_CMDLINE_LEN\s+64" , exec_override_text )
402+ and re .search (r"#define\s+AI_AGENT_EXEC_CMDLINE_MAX_ARGS\s+4" , exec_override_text )
403+ and re .search (r"#define\s+AI_AGENT_EXEC_CMDLINE_ARG_LEN\s+32" , exec_override_text )
392404 and "ai_agent_exec_override_read_argv_index" in exec_override_text
393405 and "rule->argv_index" in exec_override_text
394406 and "rule->argv_op != AI_AGENT_EXEC_ARGV_OP_EXACT" in exec_override_text
395407 and "ai_agent_exec_override_arg_matches" in exec_override_text ,
396- "AI Agent exec override must read only the configured argv index" ,
408+ "AI Agent exec override must read only bounded argv/cmdline data that old verifiers can load" ,
409+ )
410+ require (
411+ "#define AI_AGENT_EXEC_UNROLL_PATH_FACTS" in exec_override_text ,
412+ "AI Agent exec override must unroll the 64-byte path fact helper to avoid bounded-loop verifier state explosion" ,
397413 )
398414 require (
399415 "ai_agent_exec_override_read_syscall_arg" in exec_override_text
@@ -436,8 +452,10 @@ def read_source(path: Path) -> str:
436452 cmdline_prefix_match_start :cmdline_prefix_match_end
437453 ]
438454 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" ,
455+ re .search (r"#define\s+AI_AGENT_EXEC_CMDLINE_PREFIX_MATCH_WORDS\s+8" , exec_common_text )
456+ and "#pragma clang loop unroll(disable)" in cmdline_prefix_match_text
457+ and "i < AI_AGENT_EXEC_CMDLINE_PREFIX_MATCH_WORDS" in cmdline_prefix_match_text ,
458+ "AI Agent exec override must limit cmdline prefix matching to 8 words and prevent clang from auto-unrolling the comparison loop" ,
441459 )
442460 append_arg_start = exec_override_text .find (
443461 "ai_agent_exec_override_cmdline_append_arg("
@@ -461,9 +479,10 @@ def read_source(path: Path) -> str:
461479 cmdline_append_arg_text = exec_override_text [append_arg_start :read_argv_ptr_start ]
462480 build_cmdline_text = exec_override_text [build_cmdline_start :read_argv_index_start ]
463481 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" ,
482+ "#pragma unroll" in cmdline_append_arg_text
483+ and "#pragma unroll" not in build_cmdline_text
484+ and "#pragma clang loop" not in build_cmdline_text ,
485+ "AI Agent exec override must unroll only the 32-byte arg copy loop and keep argv iteration bounded" ,
467486 )
468487 require (
469488 "ai_agent_exec_override_arg_reset" in exec_override_text
0 commit comments