Repository navigation
Hatchling 0.3.0
The local-attacker release, first part. It closes what another local user could do to a running broker: a root broker that followed symlinks when it handed a cell its socket, set modes or made directories (WO-006), and agent sessions admitted by uid alone, so any process with the agent's uid could open one (WO-007). Every agent cell, the broker's own and each scheduled run's and subagent's, now reaches the broker over a connection made for it alone, and in cell mode no agent socket is bound. The broker and the agent must both be 0.3.0: a 0.2.0 agent can't use the connection a 0.3.0 cell gives it; the one hatchling binary is both. The broker also refuses nobody as the agent uid unless told otherwise. Rust API changes are marked Breaking below.
Added
HATCHLING_AGENT_ALLOW_NOBODY: the broker now refuses to start withnobody(65534) asHATCHLING_AGENT_UID, since every process running as nobody could act as the agent; this setting accepts it anyway (WO-007).
Changed
- Breaking: the broker's agent cell now reaches the broker over a connection made for it alone, inherited at the descriptor
HATCHLING_CONNECTION_FDnames, and in cell mode the broker binds no agent socket at all. Before, any process with the agent's uid that could reachHATCHLING_BROKER_SOCKETcould open a full agent session, and name any cell id in its hello; now the cell's session is the only one, and runs under the cell id the broker gave it.HATCHLING_BROKER_SOCKETis still read, and used when the broker serves without a cell. A scheduled run's and a subagent's cell get a connection of their own the same way: the helper that spawns the cell sends the broker its end over a channel given as the helper's stdin (taken off stdin first, so the cell inherits/dev/null), and no run socket is bound. With no run socket to fit a unix socket address, a scheduler directory may now be any length (WO-007, parts 2 and 3). - Breaking, Rust API:
hatchling-isolation'sCellSpechas aconnectionfield andCellaconnectionmethod, withCONNECTION_FD_VAR;hatchling-agent'sConfignames its broker withbroker: BrokerAddressinstead ofbroker_socket;hatchling-broker'sCellConfighasconnected, andserve_cell_connection,serve_cell_foreverandAgentCellare new;hatchling-sysaddskeep_across_exec,take_stdinandnet::inherited_unix_stream;hatchling-brokerdropsrun_launcher::RUN_SOCKET_NAME;hatchling-coreaddsPeerCredentials::of_spawned. - Breaking,
hatchling-sys:chown_ids, which changed ownership by path, is removed.hand_over_socketandshare_dir_with_cellchange ownership through handles opened without following symlinks, withdir_shareandowner_traversesdeciding what they do;create_private_dirmakes a directory exclusively with mode 0700,ensure_private_dirmakes or pins one, andchmod_socketsets a socket's mode through a handle. The workspace version is 0.3.0.
Fixed
- A connection to the broker that stays silent for 10 seconds before its hello is complete is closed, freeing its connection slot; before, it held the slot until the peer went away (WO-007).
- The broker sets its listener's mode, and a scheduled run's directories and the vault's, without looking a path up again. The listener's mode goes through a handle opened without following symlinks; private directories are made exclusively and set to 0700 through a handle, and an existing run root is fixed through a handle. The ingress and device endpoints take their owner from the broker's own uid rather than reading it back from the socket's path. A skill's verified-code copy gets a name no one can guess, so another local user can't pre-create it to block the skill (WO-006).
- A root broker no longer gives its socket's directory to the cell's user. That user could swap the socket for a symlink between spawns, and the broker's next handover, which went by path, would give the cell's user whatever file the link named. The directory now stays the broker's, with the cell's group allowed to traverse it and nothing more (mode 0710); a directory an earlier version handed over is taken back. The socket and the directory are each changed through a handle opened without following symlinks, and the socket must be a socket itself (WO-006).
- A cell's staging directory can no longer be pre-created by another local user to block or redirect a spawn. Each broker process makes one private staging root in the temp directory (mode 0700, a random name, created exclusively), and each cell's directory inside it gets a random name too; a name already taken, by a directory or a symlink, is skipped and never followed (WO-006).