proot/syscall/mod.rs
1//! Syscall routing: which numbers go where, and the handlers for each tier.
2
3pub mod direct;
4pub mod notify;
5pub mod nr;
6pub mod traced;
7
8use nr::*;
9
10/// Syscalls answered by the supervisor through user notification.
11///
12/// `uname` is appended at runtime only when a kernel release is faked.
13pub const NOTIFY_SYSCALLS: &[i64] = &[
14 OPEN,
15 STAT,
16 LSTAT,
17 ACCESS,
18 GETCWD,
19 RENAME,
20 MKDIR,
21 RMDIR,
22 CREAT,
23 LINK,
24 UNLINK,
25 SYMLINK,
26 READLINK,
27 CHMOD,
28 CHOWN,
29 LCHOWN,
30 TRUNCATE,
31 STATFS,
32 MKNOD,
33 UTIME,
34 UTIMES,
35 SETXATTR,
36 LSETXATTR,
37 GETXATTR,
38 LGETXATTR,
39 LISTXATTR,
40 LLISTXATTR,
41 REMOVEXATTR,
42 LREMOVEXATTR,
43 OPENAT,
44 MKDIRAT,
45 MKNODAT,
46 FCHOWNAT,
47 FUTIMESAT,
48 NEWFSTATAT,
49 UNLINKAT,
50 RENAMEAT,
51 LINKAT,
52 SYMLINKAT,
53 READLINKAT,
54 FCHMODAT,
55 FACCESSAT,
56 UTIMENSAT,
57 NAME_TO_HANDLE_AT,
58 RENAMEAT2,
59 STATX,
60 FACCESSAT2,
61 OPENAT2,
62 FCHMODAT2,
63];
64
65/// Syscalls added to the notify tier by `-0`: identity queries answered as root,
66/// identity changes accepted, descriptor ownership changes forgiven.
67pub const FAKE_ROOT_SYSCALLS: &[i64] = &[
68 GETUID, GETGID, GETEUID, GETEGID, GETRESUID, GETRESGID, SETUID, SETGID, SETREUID, SETREGID, SETRESUID,
69 SETRESGID, SETFSUID, SETFSGID, SETGROUPS, GETGROUPS, CAPSET, FCHOWN,
70];
71
72/// Syscalls served through notification instead of a ptrace stop when
73/// there is no ptrace: the trace tier plus `fchdir` (the working directory
74/// is virtual then) and the `clone` family (the child's state is snapshotted
75/// at the fork).
76pub const NO_PTRACE_SYSCALLS: &[i64] = &[
77 EXECVE,
78 EXECVEAT,
79 CHDIR,
80 FCHDIR,
81 CHROOT,
82 CONNECT,
83 BIND,
84 INOTIFY_ADD_WATCH,
85 CLONE,
86 FORK,
87 VFORK,
88 CLONE3,
89];
90
91/// Syscalls whose namespace flags are refused with `EPERM` by the filter
92/// itself, as a default container refuses them: a tracee in a mount
93/// namespace of its own could not be served by a supervisor that does the
94/// filesystem work in its own. `clone3` carries its flags in memory and is
95/// inspected by a handler instead; `setns` is refused outright.
96pub const NAMESPACE_FLAG_SYSCALLS: &[i64] = &[CLONE, UNSHARE];
97
98/// Syscalls whose dumpable-flag operations go to the listener.
99///
100/// A process that clears its dumpable flag closes `process_vm_readv`,
101/// `/proc/<pid>/mem` and `/proc/<pid>/fd` to everyone without
102/// `CAP_SYS_PTRACE`, the supervisor included, and every later path syscall
103/// would fail with `EACCES`. The filter routes `prctl(PR_SET_DUMPABLE)` and
104/// `PR_GET_DUMPABLE` here, where the flag is remembered instead of changed;
105/// every other `prctl` runs natively.
106pub const DUMPABLE_SYSCALLS: &[i64] = &[PRCTL];
107
108/// Syscalls refused with `EPERM` unconditionally.
109pub const REFUSED_SYSCALLS: &[i64] = &[SETNS];
110
111/// `CLONE_NEW*` bits of `clone`, `clone3` and `unshare` flags.
112pub const CLONE_NEWNS_FLAGS: u64 = 0x7e02_0080;
113
114/// Syscalls that take a ptrace stop so their arguments can be edited in place.
115///
116/// `inotify_add_watch` is here because a watch can only be added to the
117/// tracee's own inotify descriptor, so the path is rewritten in place.
118pub const TRACE_SYSCALLS: &[i64] = &[EXECVE, EXECVEAT, CHDIR, CHROOT, CONNECT, BIND, INOTIFY_ADD_WATCH];