|
83 | 83 | # another terminal session (terminal escape attack). |
84 | 84 | TIOCSTI = 0x5412 |
85 | 85 |
|
| 86 | +# Dangerous prctl(2) options — these allow a sandboxed process to |
| 87 | +# weaken its own confinement. |
| 88 | +PR_SET_DUMPABLE = 4 # re-enable /proc/pid/mem writes |
| 89 | +PR_SET_SECCOMP_OPT = 22 # change seccomp mode from within sandbox |
| 90 | +PR_SET_SECUREBITS = 28 # alter LSM security bits |
| 91 | +PR_SET_PTRACER = 0x59616d61 # allow arbitrary ptrace attach |
| 92 | +_DANGEROUS_PRCTL_OPS = ( |
| 93 | + PR_SET_DUMPABLE, |
| 94 | + PR_SET_SECCOMP_OPT, |
| 95 | + PR_SET_SECUREBITS, |
| 96 | + PR_SET_PTRACER, |
| 97 | +) |
| 98 | + |
86 | 99 |
|
87 | 100 | # --- Per-architecture configuration --- |
88 | 101 |
|
@@ -289,6 +302,8 @@ def _build_arg_filters() -> bytes: |
289 | 302 | Plain forks fall through to the main filter (USER_NOTIF if |
290 | 303 | clone is in the notif list, or ALLOW if not). |
291 | 304 | - ioctl(2): Block TIOCSTI (terminal input injection). |
| 305 | + - prctl(2): Block dangerous options (PR_SET_DUMPABLE, |
| 306 | + PR_SET_SECCOMP, PR_SET_SECUREBITS, PR_SET_PTRACER). |
292 | 307 | """ |
293 | 308 | insns = bytearray() |
294 | 309 |
|
@@ -316,6 +331,18 @@ def _build_arg_filters() -> bytes: |
316 | 331 | insns += _bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, TIOCSTI, 0, 1) |
317 | 332 | insns += _bpf_stmt(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | ERRNO_EPERM) |
318 | 333 |
|
| 334 | + # --- prctl: block dangerous options that weaken the sandbox --- |
| 335 | + insns += _bpf_stmt(BPF_LD | BPF_W | BPF_ABS, OFFSET_NR) |
| 336 | + n_ops = len(_DANGEROUS_PRCTL_OPS) |
| 337 | + # if nr != prctl, skip: 1 (load arg0) + n_ops*2 (check+deny each) |
| 338 | + skip_count = 1 + n_ops * 2 |
| 339 | + insns += _bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, _SYSCALL_NR["prctl"], 0, skip_count) |
| 340 | + # Load prctl option (arg0) |
| 341 | + insns += _bpf_stmt(BPF_LD | BPF_W | BPF_ABS, OFFSET_ARGS0_LO) |
| 342 | + for op in _DANGEROUS_PRCTL_OPS: |
| 343 | + insns += _bpf_jump(BPF_JMP | BPF_JEQ | BPF_K, op, 0, 1) |
| 344 | + insns += _bpf_stmt(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | ERRNO_EPERM) |
| 345 | + |
319 | 346 | # --- socket: block NETLINK_SOCK_DIAG (hides host socket info) --- |
320 | 347 | _AF_NETLINK = 16 |
321 | 348 | _NETLINK_SOCK_DIAG = 4 |
|
0 commit comments