Skip to main content

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];