ADR 0266: the setuid search's bound is 15 minutes, and the two routes and the restart condition the review of 2026-10-09 found
mesh/merge-gate pass: the change touches no module of the mesh's graph
mesh/repo-check pass: its merge-check.sh passed
mesh/delivery superseded: a newer head of the same pull request

Item 10 said two minutes; the engine's bound is 15, with a two-minute limit
inside it still to settle. What still remains now names a build from another
repository registering a module (mesh-controller 174), the forge's tools
changing its protection (mesh-catalog 153), and the urgent condition every
engine restart raises (mesh-controller 175).
This commit is contained in:
jochen
2026-10-09 11:49:25 +02:00
parent ee314a26ca
commit d7999e6fc9
@@ -153,8 +153,13 @@ the C locale. It finds a way to root when the account:
tool runner's credential is one of those;
10. could run a program no installed package owns that is setuid with owner root, or setgid with group root
whoever owns it, on any local filesystem mounted without `nosuid` (container and image layers, network
and pseudo filesystems excepted). The engine searches for these at most hourly and gives the search two
minutes;
and pseudo filesystems excepted). The engine searches for these in the background, at most hourly, and
lets one search run for at most 15 minutes. Until the first search after the engine starts has finished,
the verdict is *not judged yet*. *Corrected 2026-10-09: this said the search gets two minutes; the engine's
bound on a search is 15 minutes (mesh-host pull request 61). Its `find` and the package queries still carry
a two-minute limit of their own inside that bound, so as written a search longer than two minutes ends
incomplete before the 15 minutes are reached; which of the two limits holds is for that pull request to
settle;*
11. lives on a machine whose kernel leaves hard or symbolic links to other accounts' files unprotected
(`fs.protected_hardlinks` or `fs.protected_symlinks` is 0).
@@ -313,6 +318,34 @@ found around it and are closed on the mesh's main line:
- **The tool runner on the control node is still the operator account** (Considered Options), so a tool
found tomorrow that reads, writes or runs a caller's path or command is a way round this record until it is
bounded. Each is a defect of that tool, found by review.
- **A build from another repository registered a module** (found in review, 2026-10-09). The controller's
`build` verb cloned any repository as given, and the outcome registered the module its `module.json` named,
from that repository: a module is registered by name and its source overwritten, and "only a commit on the
trunk is published" (ADR 0238) checked the trunk of the repository built. An agent that made a repository,
or forked the catalogue or the node-engine, and committed a `sudo` module granting itself a rule without a
password, had the next push make it root on every node. `rebuild`, `replay --register` and `assign` with
`build` reached the same take-in. Closed by mesh-controller pull request 174, once merged after pull request
164: an outcome registers a module only from the repository the catalogue already builds it from, a new
module only from a repository the catalogue already builds another from (a merge adding one), and anything
else only when the build was asked at the controller's terminal; through a verb, a build of a repository
the catalogue builds nothing from is not asked at all, and a failed gate puts back only a build of the
module's own repository.
- **The forge's tools could change the forge's protection** (found in review, 2026-10-09). `gitea_api` sent
any call with a token minted for the forge's administrator, `write:admin` included: an agent could drop a
branch's protection or its required checks, set the merge check's status, write to the default branch,
delete and recreate a repository the mesh builds from, or merge its own pull request past the checks; and
`gitea_branch_protection_set` could weaken a rule. Closed by mesh-catalog pull request 153: `gitea_api`
reads anything but the forge's administration and writes only what an author writes, protection is only
made stronger, a merge needs every required status a success and merges only the head that was checked, a
guarded repository is not deleted, and the token is minted without `write:admin`. A merge after the
operator's yes, of a pull request whose checks passed, works as before. The token still belongs to the
forge's administrator; a non-admin account for the tools is a follow-up.
- **Every node-engine restart raises `agent-can-become-root`.** Until the engine's first search for setuid
programs finishes (§3 item 10), the verdict is *not judged yet*, and the self-check (§4) raises the urgent
condition on every restart. Proposed in mesh-controller pull request 175: while that first search is within
its bound (15 minutes, and one statement more), the condition is not raised; the account is still not
confined, `node show` still says not judged, and the condition is raised as before once the search fails,
runs out its bound or finds a way to root.
- **The self-check judges this record's account only.** ADR 0259's own root probe (mesh-controller pull
request 154) asks the same question through the `sudo` module; it must call this record's judgement, one
function, rather than keep a second answer.