summaryrefslogtreecommitdiff
path: root/docs/v9fs.md
blob: 2646065810129d7848bb133ac4a90609683b4779 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# Tty9p: a terminal with a kernel 9P mount

On Linux, `Tty9p` (`SPC n 9`) opens a terminal below this pane with the
session mounted through the kernel's v9fs. The pane asks for your sudo
password, mounts, and starts your shell as your normal user (with your
supplementary groups). The shell gets `PARDES_MOUNT`, the mountpoint:

```sh
cat "$PARDES_MOUNT/index"
cat "$PARDES_MOUNT/pane/$PARDES_PANE/body"
echo 'Msg hello' > "$PARDES_MOUNT/exec"
n=$(cat "$PARDES_MOUNT/pane/new")
```

The files are those of [fs.md](fs.md). The mount lives in that pane's
private mount namespace: other panes and the editor do not see it, so a
Look at a path under `$PARDES_MOUNT` opens nothing. Each `Tty9p` makes its
own mount and takes one of the session's 16 Unix/TCP connection slots. It
works in TTY, SDL and detached sessions (the session host starts the shell,
not an attached frontend). Dump/Restore does not remake the mount.

## Setup

The build installs `pardes-v9fs` beside `pardes`; the host looks for it
beside its own executable, or at `PARDES_V9FS_HELPER` (an absolute path).
A running editor keeps the code it started with.

Linux needs `9p` and its Unix transport (`9pnet_fd`); mounting needs
`CAP_SYS_ADMIN`, which sudo supplies. The launcher runs `sudo -E` (local
policy must allow it) and restores the caller's `PATH` after dropping
privileges. Nothing setuid, no passwordless sudo rule and no FUSE is
installed. The helper takes explicit mount paths and a command; it is not a
restricted privilege broker, so do not grant it passwordless sudo.

## How it works

`Tty9p` starts the normal shell and queues a quoted helper command, which
bash and fish run once their prompt is ready, as a foreground job, so sudo
uses the terminal. A failed or cancelled authentication returns to that
shell, as does exiting the mounted one. The unprivileged launcher makes a
private temporary mountpoint and runs sudo; the elevated helper makes a
private mount namespace, mounts the session's socket with
`trans=unix,version=9p2000,cache=none,access=any,nosuid,nodev,noexec`, drops
every root id and capability, and executes the shell. The namespace, and
the mount, go when its last process exits. Code: `src/linux/v9fs.zig`.

Linux follows `O_TRUNC` with a `Twstat` of zero length and an `mtime` hint;
pardes takes the truncation and drops the hint.

## Tests

```sh
zig build v9fs-terminal-test -Dplatform=tty   # builtin, launcher, cleanup; a sudo stand-in, no mount
zig build v9fs-driver-test -Dplatform=tty     # the probe launcher, no privileges
sudo -v; zig build v9fs-test -Dplatform=tty   # a real kernel mount (sudo -n); fails, not skips, without it
```