Expand description
Handlers for the syscalls that take a ptrace stop when ptrace is available, served through user notification when it is not.
A notification cannot change registers, only answer the syscall, let it continue, or install a descriptor into the tracee. Three tricks cover the former ptrace tier:
chdir,fchdirandchrootare answered without running: the working directory is virtual (procs), every path handler resolves relative paths against it, and the kernel’s own cwd of every tracee stays pinned to the alias directory.connectandbindare performed by the supervisor on a socket of the same type and flags, which then replaces the tracee’s descriptor throughADDFDwithSETFD.execve,inotify_add_watchandO_PATHopens must run in the tracee with a different path. The path string is overwritten in place, through/proc/<pid>/mem, with a name of one or two bytes that resolves inside the alias directory, which the kernel cwd makes reachable from any process:eis the exec trampoline (seeexec::shim) and a transient one-character symlink stands for any other host path. A symlink to be reached by a bare name, which no<alias>/<name>fits, is reached through a hard link to it instead, the same inode. The syscall then continues. Once the task has consumed the argument, the original bytes are put back, but only when the memory still holds exactly what was written: a buffer may have been freed or reused by then, and must not be touched if so.
clone and its relatives are notified only to snapshot the parent’s
state for the child, see procs.
In the guest-stub restricted mode (see guest_stub) the strings these
handlers rewrite are the stub’s copies in the mailbox, with room for any
host path, so the full host path is written and nothing is put back. An
exec is planned from the staged copy and answered with the mailbox
descriptor installed for the trampoline, which the stub then execs itself.
Structs§
- Placed 🔒
- A transient alias in place: the bytes that replace the tracee’s string, and the hard link to remove once the syscall has consumed them.
Enums§
- Form 🔒
- How a transient alias stands for its target.
Constants§
- ALIAS_
CHARS 🔒 - Characters available for transient alias names;
eandrare the trampoline and its records. - CLONE_
THREAD 🔒 CLONE_THREAD: the new task shares the process, nothing to inherit.- CLONE_
VFORK 🔒 CLONE_VFORK: the child shares the parent’s memory until it execs.- RESTORE_
TIMEOUT 🔒 - Longest wait for a continued syscall to return before restoring anyway.
- SETTLED_
CPU 🔒 - CPU time a resumed task must have run for its syscall to be past the argument copy and the path walk, with a wide margin over the microseconds those take.
Statics§
- ALIASES 🔒
- Which names are in use, and where the next search starts: names are handed out round-robin so a name just released is not re-pointed while the kernel may still be walking through it.
- STAGING 🔒
- Directories holding hard links to symlinks, one per mount reached so far.
Functions§
- acquire_
alias 🔒 - Takes a free one-character alias name, the least recently handed out.
- binfmt_
misc_ 🔒matches - Whether a registered
binfmt_mischandler would run a file we do not recognize, by the same magic or extension test the kernel applies. - check_
executable 🔒 - Refuses a plan the kernel would refuse, with the kernel’s errno.
- check_
loadable 🔒 - Refuses, in the guest-stub mode, a plan the trampolines’ loaders cannot
carry out, and tells which trampoline loads the rest. Besides what the
kernel refuses (see
check_executable) that is a format onlybinfmt_miscwould run, and a 32-bit program where the i386 trampoline cannot run (a kernel without ia32 emulation). A nested launch, which the trampoline sets up first, is only classified. - commit_
trapped 🔒 - Writes the trampoline’s record for a planned exec in the guest-stub mode and marks the process as about to run it.
- cpu_
time 🔒 - CPU time thread
tidhas run, in nanoseconds, from/proc/<tid>/schedstat. - dispatch
- Routes a former trace-tier syscall to its handler;
Nonefor any other. - do_
chroot 🔒 chroot: the guest root is a no-op, anything else is refused as it would be for an unprivileged process.- do_
clone clone/fork/vfork/clone3: refuse a new namespace, snapshot the parent for the child without ptrace, then continue.- do_
execve 🔒 execve/execveatthrough the trampoline.- do_
execve_ 🔒trapped execve/execveatin the guest-stub restricted mode.- do_
inotify_ 🔒add_ watch inotify_add_watch: the watch goes on the tracee’s own descriptor, so the path is rewritten to a transient alias, which the tracee then walks.- do_
open_ path - An
O_PATHopen without ptrace. - do_
sockaddr 🔒 connect/bindon anAF_UNIXpath, done on a replacement socket.- do_
socketcall socketcall(call, args)from an i386 tracee:bind(2) andconnect(3).- hello
- Answers the trampoline’s
layout::HELLO: the exec planned for the process has happened, so it now runs the program, in the view the plan named. - io_
errno 🔒 - The errno of an I/O error,
EIOfor one without. - kernel_
walks_ 🔒alike - Whether the kernel, walking
pathfrom the tracee’sdirfdby itself, reacheshost. - link_
nofollow 🔒 linkatwithoutAT_SYMLINK_FOLLOW: a hard link tohostitself, a symlink included.- open_
host 🔒 - Opens a host path for injection.
- place_
alias 🔒 - Places the alias
nameforhostso that its path fits inroombytes, the tracee’s string and its NUL. - plan_
first_ trapped - Plans the first tracee’s exec in the guest-stub restricted mode, which the supervisor itself sets up rather than a stub: the tracee execs the trampoline through the allow gate with the mailbox it inherited.
- ptrace_
usable - Whether ptrace can be used from here.
- readlink_
alias_ fd readlinkatwith an empty path on a descriptor opened through a hard link alias: the answer comes from the descriptor’s own inode, reopened through/proc, since the link it was opened by is gone by then and its name may stand for something else.- readlink_
reopened 🔒 - Reads the target of the symlink a
/proc/<pid>/fd/Nlink leads to, by reopening itO_PATHhere, which lands on that inode whether or not its name still exists. - release_
alias 🔒 - Returns an alias name to the pool. The symlink stays until the name comes round again.
- remove_
staging - Removes the staging directories, at exit.
- restore_
if_ 🔒intact - Puts
origback ataddrin processpidif the memory still holds exactly the rewrite, i.e.writtenfollowed by the rest oforig. - retry 🔒
- Runs a lookup again while it finds a symlink swapped in since the walk.
- rewrite_
staged 🔒 - Replaces a path the guest stub staged with its host path and lets the syscall continue on it.
- set_cwd 🔒
- Moves the virtual working directory to
path, withchdir’s own checks. - shim_
passthrough - Lets the trampoline’s own syscalls through untranslated.
- socket_
description 🔒 - Type and descriptor flags of a tracee’s unix socket.
- stage_
hard_ 🔒link - Makes a hard link named
nametohostin a staging directory on its mount, creating one under the first ofcandidatesthat allows it. - staging_
candidates 🔒 - Where a staging directory may be created, in order: the user’s cache directory, beside the rootfs, and the temporary directory.
- transient_
rewrite 🔒 - Rewrites a path string in the tracee to a transient alias, continues the syscall, and puts the string back once the syscall has consumed it.
- under_
alias 🔒 - Whether
hostlies in the alias directory or a staging directory. - unstage 🔒
- Removes the hard link an alias was placed through, once the syscall has consumed the rewritten path; a descriptor opened through it keeps the inode.
- wait_
syscall_ 🔒consumed - Waits until the continued syscall has consumed its rewritten argument.