summaryrefslogtreecommitdiff
path: root/pim/doc/gotchas.md
diff options
context:
space:
mode:
authorCalvin Morrison <calvin@pobox.com>2026-08-18 21:02:41 -0400
committerCalvin Morrison <calvin@pobox.com>2026-08-18 21:02:41 -0400
commitc2c6a9eb419ebfc0ea5cac25e199362da25f1013 (patch)
tree4834f69e2e372836d8814d2ff788ea5ee956cfbe /pim/doc/gotchas.md
parent978b9cde1b7f448db5816a0d15fe9f72a94e3341 (diff)
netfs: name what is served instead of listing what is hidden
/net/tcp/trans, /net/udp/trans and /net/icmp/trans install kernel address translations. devip gates them with iseve() (devip.c:406), and through this server that is fw's identity, not the caller's -- fw does every open with its own credentials and never looks at the client's. On a machine where fw runs as eve, which is the ordinary case, there was no gate at all. Demonstrated in a sandbox with an empty rule set: === baseline: real /net, no fw === echo: write error: local ip not found === inside the sandbox === connect: refused (as expected) append via fw: local ip not found create via fw: bad process or channel control request Both errors come from transwrite itself, so the open succeeded and fw imposed nothing; and the second proves the OTRUNC path is reachable, which runs transwrite(p, nil, 0, 0) and flushes the whole table before the write is even parsed. /net/log was half closed: the write was refused so a program could not turn tracing on, but reading it was the leak, and anything an administrator turns on elsewhere is then readable from inside the sandbox. ipifc data was refused rather than hidden, against the principle stated ten lines above it for ether and ipmux, and its snoop file is the same wire and was not mentioned at all. The pattern is the problem. A list of things to deny has now been wrong twice, in the same way the ctl filter was, and the answer is the one that worked there: nothing is served unless it is named. Protocol directories come from a list of names rather than from "has a clone file", because devether has one of those too and #l bound into /net would have become a protocol; a protocol missing from the list is one nobody can reach, which is the safe way to be out of date. Within one, only clone, stats and the conversation files, and for ipifc not clone, not data, not snoop. In the root, only cs and dns writable and arp, bootp, iproute, ipselftab and ndb readable. Splitting the path also disposes of a name like "tcp/../.." arriving as a single walk element from a client speaking 9P straight to the server: more than three components, or an empty one, is not a path this server handed out, so it is not one it will honour. Sixteen new checks. Against the previous netfs.c six of them fail -- trans served, log served, ipifc data and snoop served, and both listing checks -- while cs, arp, ndb, iproute, ipifc status, clone and connect filtering all still pass, which is the half that matters. They ask by stat rather than by read: reading log or a data file blocks until traffic arrives, so reading would hang on exactly the build that still serves them, and a test that hangs on a regression is worse than none. 46 pass, twice in a row with no cleanup between. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Diffstat (limited to 'pim/doc/gotchas.md')
0 files changed, 0 insertions, 0 deletions