Conversation
Zero capabilities was being treated as containment. brk, munmap and the wayland shm path took a guest number and acted on it, so a guest could unmap the personality or ask for a buffer no machine has. Limits come from one address plan in guest/layout.rs now. They had already drifted: only map.rs knew the mapping cursor's neighbour is EXEC_BASE and not the stack. Paths resolve to a Key only file::resolve can mint and the store wrappers take nothing else, so /linux is the root by construction. PT_INTERP and library mappings were loaded unproven, which left the attestation gate on the main image doing nothing useful. Both proven, ELF arithmetic checked. argv was read under MAX_PATH, so long arguments failed execve with nothing saying why. The resolver hands out 100.64/10 addresses and maps them back at connect, and the installer runs over the mixnet. resolve_host in net_sockets still does a clearnet lookup and is not fixed here. Package bytes are still unauthenticated, so place_entry refuses to vouch for them and the exec gate refuses what lands. tar::entries stopped at the first end-of-archive block, which in an apk is the end of the signature stream, so unpack had never written a file. Mirrored in python: one stream, sig+ctl+data, unterminated middle, garbage tail.
A runtime installs handlers before main and checks the return. Answering ENOSYS made programs abort at startup that would otherwise have run to completion, because most of them never raise anything. rt_sigaction, rt_sigprocmask and sigaltstack now succeed and record what was asked. Nothing is ever raised. Delivery means pushing a frame onto a guest thread's stack and redirecting it, and the trap mechanism hands out a register frame without any way to rewrite one, so it cannot be done from here yet. That limit is written in the file rather than hidden behind the success: a program that depends on SIGALRM will hang rather than misbehave quietly, which is the failure that can be diagnosed. SIGKILL and SIGSTOP are refused as uncatchable, as Linux refuses them.
net.sockets offers socket, connect, send, recv, close and a readiness poll, keyed by the caller's pid, which maps onto the Linux calls almost one to one. A guest's descriptor now holds a handle that service issued to this capsule, so a guest reaches only the sockets opened for it. read and write route by descriptor kind, so a program that treats a socket as a file, which most do, works without knowing the difference. Closing one closes the handle behind it. poll answers for every descriptor. A file or a console is always ready, which is what Linux reports too. A socket is asked one handle at a time, because that is the shape of the readiness call the service serves, and inventing a batched form here would mean a second protocol with nobody on the other end. The opcodes are transcribed rather than imported: the server is a binary and its protocol module is not a library. The file they came from is named beside them, since a number that changes there and not here is a wrong operation rather than a failed one.
supervised_asid returned an asid and dropped the lock that made it true, so peer map, unmap, copy and protect all ran against an asid the supervisor no longer held. It returns the guard with it now. The entry stub saves the callee-saved five plus a pad so a forked child resumes on the parent's register state. Nothing else on the path writes them to memory and a handler's prologue may already be using them, so it happens in the stub or not at all. Six slots keeps the frame 16-byte aligned and leaves existing offsets alone. libc gains wrappers for foreign exec, fork and resume, peer TLS and unmap, and the local signing and consent calls.
eKisNonos
force-pushed
the
linux/threads
branch
from
September 21, 2026 14:26
cc4d22c to
198d4a2
Compare
eKisNonos
force-pushed
the
linux/signals
branch
from
September 21, 2026 14:26
6babc8b to
5f1ce5f
Compare
eKisNonos
force-pushed
the
linux/signals
branch
from
September 21, 2026 15:02
5f1ce5f to
747edf5
Compare
Collaborator
|
Merge blocker: symbols this PR needs are not defined anywhere. This PR uses Could the author push the branch that defines them, or say which PR adds them? Until then this PR can't compile, even once its stack base (#506) has merged. |
Collaborator
|
Landed on main through #559 (merge commit |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Builds on #511. Two pieces: signal dispositions, and sockets with poll.
Signals are recorded and never delivered, and the code says so rather than hiding it behind a success. A runtime installs handlers before main and checks the return, so answering ENOSYS made programs abort at startup that would otherwise run to completion, because most of them never raise anything. rt_sigaction, rt_sigprocmask and sigaltstack now succeed and remember what was asked. Delivery means pushing a frame onto a guest thread's stack and redirecting it, and the trap mechanism hands out a register frame with no way to rewrite one, so it cannot be done from here yet. A program that depends on SIGALRM will hang rather than misbehave quietly, which is the failure you can diagnose. SIGKILL and SIGSTOP are refused as uncatchable, as Linux refuses them.
Sockets go over net.sockets, which already offers socket, connect, send, recv, close and a readiness poll, keyed by the caller's pid. That maps onto the Linux calls almost one to one. A guest's descriptor holds a handle the service issued to this capsule, so a guest reaches only the sockets this capsule opened for it. read and write route by descriptor kind, so a program that treats a socket as a file, which most do, works without knowing the difference, and closing the descriptor closes the handle behind it.
poll answers for every descriptor kind. A file or a console is always ready, which is what Linux reports for them. A socket is asked one handle at a time, because that is the shape of the readiness call the service serves; a batched form invented here would be a second protocol with nobody on the other end.
The net.sockets opcodes are transcribed rather than imported, because the server is a binary and its protocol module is not a library. The file they came from is named beside them, since a number that changes there and not here is a wrong operation rather than a failed one.
Not built, like the rest of this stack.