Files kept yours, whoever else logs in
link-files is how Link keeps files on this machine: its folders, and
reading and writing them so no other user can swap, read or change
what's in them.
The home and machine folders
home_dir() is the user's home folder, . without an absolute
HOME; code that deletes or trusts what's there uses try_home_dir(),
an error when HOME is unset, empty or relative. A home that is a link
is read through it, so every path under it is the one it leads to, as
it is inside a sandbox.
~/.lnk
machine_dir() is this machine's folder, ~/.lnk, and
try_machine_dir() the same or an error when it can't be an absolute
path. LNK_MACHINE_DIR (MACHINE_DIR_VAR), when absolute, puts it
elsewhere for one process and what it runs: a sandbox's session whose
own settings can't be in a folder it writes.
Shared state locations
Link-owned persistent state lives below .lnk in the relevant home,
including an isolated harness home. state::path(home, area) names each
location from the state::Area table, so every caller agrees on it.
Private folders and writes
What Link writes that may hold a secret is readable by this user alone, in folders no other user made first.
create_private_dir
Creates a folder readable only by this user (0700 on Unix), with any
missing parents (also 0700), and takes away others' permissions from
one already there. A folder, or a link to one, that another user owns
is refused: in a shared folder such as /tmp they could have made it
first, to swap what's put in it. check_own_dir refuses a folder that
isn't this user's, itself and not through a link to another's.
write_private
Writes a file readable only by this user, atomically, creating its
folder (0700) if it is missing; an existing ~/.lnk is made private
too. Two writes at once each leave the file whole, the last one's; a
caller that reads, changes and writes it back holds a lock of its own.
lock_file
Holds a lock file until it's dropped, and the next to ask waits. Its
folder is made private, and the file is opened in place, never replaced
and never through a link (O_NOFOLLOW), 0600, so every holder locks
the same file.
private_temp_dir and random_token
private_temp_dir(name) is a new folder in the system's temporary
folder, lnk-<name>- and a random suffix, 0700, made here and now (as
mkdtemp): never one another user made first. random_token() is 32
random hex characters, for tokens and secrets Link makes, such as a
harness's local API key, a pairing code or a proxy's tag.
write_program and copy_program
Write or copy a program (mode 755), never open for writing in this
process: one this process wrote itself could fail to run ("Text file
busy") while a child another thread forked still held the write open,
so a short-lived install writes it, from a copy this process wrote
and never runs.
Reading a file whose writer matters (fs)
read_trusted reads a file once, where it really is, and no more of it
than a limit, naming that limit's owner in its error. A link is
followed once, here, and the file opened with no link left and checked
to be the one its real path names, so a folder swapped on the way opens
nothing else.
Trust
Who it must have been written by: the users who may own it, and with
ancestors each folder on its way, a folder its others write let by
only with its sticky bit, as /tmp; the mode bits none may have,
0o022 by default; and with no_link, a link at its path refused
instead of followed.
What it refuses
It's opened without waiting, so what isn't a file (a pipe put there) is
refused, never waited on. A missing file is an error whose root cause
is that io::Error.
Folders another may write (nofollow)
A harness's folder, an agent's Home or a skill's download, walked by
lnk outside the sandbox without following a link. Each name is
opened relative to its folder's handle (Dir) with O_NOFOLLOW, so a
link swapped in after a check is refused rather than followed, and a
file is read or written through the handle it was opened as.
Traversing a private parent
Dir::search_unlinked opens a parent for access to its children without
following a link at the parent. On macOS it uses O_SEARCH, so a sandbox
can grant selected children without letting the harness list their
parent. Children are opened separately with their own access checks.
Opening a file
Dir::open_file refuses a link and a device without waiting on it.
Opened to write, a file with another name too (a hard link) is refused,
since what's written here would be written there, and O_TRUNC is
refused, since it would empty that other name before the refusal.
Copying and removing
Dir::remove_all and Dir::copy_into go at most DEEPEST, 32
folders down, and refuse a folder past it. A copy says what it does
with a link: made again as the same link, left out, or refused, nothing
of it written, and reports what it copied and left out.