|
2 | 2 | /* |
3 | 3 | * branch_tracker.bpf.c — BPF LSM program for branch process tracking. |
4 | 4 | * |
5 | | - * Hooks task_alloc and task_free to inescapably track all descendants |
6 | | - * of registered branch root PIDs. Supports atomic fork-denial during |
7 | | - * branch teardown. |
| 5 | + * Hooks task_alloc, task_free, and task_kill to inescapably track all |
| 6 | + * descendants of registered branch root PIDs. Supports atomic |
| 7 | + * fork-denial during branch teardown and cross-branch signal isolation. |
8 | 8 | * |
9 | 9 | * Compile: |
10 | 10 | * clang -g -O2 -target bpf -D__TARGET_ARCH_x86 \ |
@@ -62,6 +62,43 @@ int BPF_PROG(branch_task_alloc, struct task_struct *task, |
62 | 62 | return 0; |
63 | 63 | } |
64 | 64 |
|
| 65 | +/* |
| 66 | + * LSM hook: task_kill — fires on signal delivery (kill, tkill, tgkill). |
| 67 | + * |
| 68 | + * Enforces cross-branch signal isolation: |
| 69 | + * - Untracked process → any target: allowed (parent/orchestrator) |
| 70 | + * - Tracked process → same branch: allowed |
| 71 | + * - Tracked process → different branch or untracked: denied (-EPERM) |
| 72 | + * |
| 73 | + * This prevents a child in one branch from killing processes in |
| 74 | + * another branch or the parent orchestrator. |
| 75 | + */ |
| 76 | +SEC("lsm/task_kill") |
| 77 | +int BPF_PROG(branch_task_kill, struct task_struct *target, |
| 78 | + struct kernel_siginfo *info, int sig, |
| 79 | + const struct cred *cred) |
| 80 | +{ |
| 81 | + __u32 sender_pid = bpf_get_current_pid_tgid() >> 32; |
| 82 | + __u64 *sender_bid = bpf_map_lookup_elem(&branch_pids, &sender_pid); |
| 83 | + |
| 84 | + /* Untracked sender (parent/orchestrator) — always allow. */ |
| 85 | + if (!sender_bid) |
| 86 | + return 0; |
| 87 | + |
| 88 | + __u32 target_pid = BPF_CORE_READ(target, tgid); |
| 89 | + __u64 *target_bid = bpf_map_lookup_elem(&branch_pids, &target_pid); |
| 90 | + |
| 91 | + /* Target is not tracked — deny (protects parent). */ |
| 92 | + if (!target_bid) |
| 93 | + return -1; /* -EPERM */ |
| 94 | + |
| 95 | + /* Both tracked — allow only within the same branch. */ |
| 96 | + if (*sender_bid != *target_bid) |
| 97 | + return -1; /* -EPERM */ |
| 98 | + |
| 99 | + return 0; |
| 100 | +} |
| 101 | + |
65 | 102 | /* |
66 | 103 | * LSM hook: task_free — fires when a process exits. |
67 | 104 | * |
|
0 commit comments