Skip to content

Next main push: the software images, the toolkit and the browser - #470

Merged
DevomB merged 290 commits into
mainfrom
batch-images-browser
Oct 16, 2026
Merged

DevomB merged 290 commits into
mainfrom
batch-images-browser

Conversation

@DevomB

@DevomB DevomB commented Oct 13, 2026

Copy link
Copy Markdown
Owner

Next main push: the software images, the toolkit and the browser, over main as it is. Each PR below has its own non-author read; this PR exists for CI on the combined head and as the record of what the push carries.

Proof: the Distro runs on this branch. Main's tree will equal a proven head of this branch, or this branch merged with main's newer proven pushes.

DevomB added 30 commits October 13, 2026 00:33
…not the root's

--strict refuses an accepted entry that matches nothing, and every entry of the root's list names an object
of the root's, so the probe's audit failed on all of them.
…wn, keyed by the base system they are built over

make images keeps each image whose fingerprint still matches its inputs and builds the rest, so a run that
changes neither an image nor the base system builds none; a tag still builds from nothing.
…d list, and shows every finding before it fails
…libepoxy and GTK's Wayland backend compile against, and no EGL library
… the tree check

# Conflicts:
#	tools/check-image-tree.sh
…their own keyed by their lock, each named in sources/ by a link
…h reasons, drops libtool's archives, and takes GLib's licences from LICENSES/
…efox 153.4.0esr, Rust 1.98.1, LLVM 23.1.3, cbindgen and nasm, with Mozilla's, Rust's and LLVM's keys pinned and fetched from their own sites
… held to the hash the lock gives, for cbindgen's offline build
…s restore, and is saved with images/ set aside
DevomB added 28 commits October 15, 2026 22:49
…ion is back, not while it is being suspended

Round 5 (38849928400) failed the suspend suite's nothing-else-waits on a havoc that started in the middle
of `kryptik suspend --awake`. The chrome's watcher opened its --waiting window whenever, at a look,
kryptik-state was not suspended and a kryptik-zone-* device was. kryptikd suspends each zone's volume
before the state partition, whose /var holds the volumes, so a look in between found work waiting with
the state partition still up. The window's terminal then started reading the user's home as the state
partition went, and stopped there in D. Main's suspend was fast enough between the two that the
once-a-second look missed it; the batch's, with the images' devices, is not.

The watcher now opens the window on the state partition's return from a suspension it saw: it notes
the partition suspended, and on its next look with the partition up asks for whichever zones still
wait. That is "once the state partition is back after a sleep", which the loop's comment already said.
A second sleep that leaves a zone waiting asks again, where the old test of the waiting set's change
did not.
…zone's passphrase once the state partition is back, not while it is being suspended
…t, not forked Pythons

Round 5 (38849928400) never finished its zones suite: the serial line stops after the time checks, at
the pids-limit storm, which forked Pythons in untrusted until pids.max refused. fe1d629 raised
untrusted's pids_max from 512 to 2048 for the browser's threads; 2048 sleeping interpreters fill the
3 GiB VM, untrusted's memory_max of 4G bounds nothing below that, and with no swap the guest stalled
past zrun's 60 s.

The storm is now one Python starting daemon threads with 64 KiB stacks until the start fails: pids.max
counts threads as it counts processes, and threads are what the raise was for. That is about 128 MiB at
2048, and every thread ends as the interpreter exits. The check is unchanged: at most the limit, at
least half of it, and the zone survives. clone3 gets ENOSYS from the zone's filter, so glibc's threads
come by clone, which it allows.
…tarts threads to untrusted's limit, not forked Pythons
…a browser check fails

A kill's audit line names one call, so a second kill would take another round. After the last
key step, a failed browser-window or browser-stays-up runs Firefox as the user in zone 0 under
kryptikd seccomp-trace --zone untrusted, in a mount and pid namespace of its own with untrusted's
/usr set bound over /usr and no render or sound node. The filter notifies instead of killing: a
soft refusal gets the zone's errno, a kill ENOSYS, and Firefox goes on. The counts of each
refused call go on a FAIL line, browser-window-trace, which the host prints.
…ed's filter refuses Firefox, after a browser check fails
…he chrome still asks for that zone's passphrase

#538 opens the chrome's waiting window on the state partition's return from a suspension. A seal that
wipes a zone volume's key and then fails, at another volume or at the state partition, never suspends
the state partition: seal() thaws the zones whose volume still has its key, and the others keep waiting
with no return to see, so no window opened for them, only the menu's WAITING and p<N>.

seal() now counts such a failure in /run/kryptik-launch/left-waiting, which group kryptik reads beside
the launch socket, writing the next count and renaming it into place. The chrome's watcher takes a new
count as it takes the state partition's return, having read the count it starts with, so an old one
opens nothing. A seal that wiped nothing before failing counts nothing.

kryptikd's unit test counts twice, restarts from a count it cannot read, leaves no temporary file, and
does nothing where the directory is missing. laptop.md's zone-volume step says it.
…aemon's umask

fs::write left the file's mode to the serve process's umask; a 077 one would hide the count from the session, which reads it as group kryptik. write_atomic gives it its mode, an O_NOFOLLOW temporary named for the process and a sync, as kryptikd writes its other such files; the test checks the mode.
…restarts

The check list said a zone naming a corrupted image is refused until the image is fetched again.
images.rs refuses a mapping dm-verity has marked corrupted until the machine restarts, as the
description above it says. What a fetch does is the store's: an update that carries the image
replaces the stored copy, since images_keep keeps one only while its size and SHA-256 match the
list's.
…e's key went counts itself, so the chrome still asks for that zone's passphrase
…oid's source mirror, which keeps the same archive

libglvnd 1.7.0 came from gitlab.freedesktop.org's archive alone, and main's first run after the browser
fetches the toolkit's sources cold, as freedesktop.org's hosts have failed such fetches before. Void
Linux's source mirror keeps the very archive: libglvnd-v1.7.0.tar.gz at
sources.voidlinux.org/libglvnd-1.7.0/, 839,820 bytes, SHA-256 2b6e15b0...f2f3d, the lock's. Debian's
orig tarball (073e7292...) and Fedora's lookaside copy (8797914f...) are other archives of the tag and
would not pass the lock; Alpine and BLFS keep none.

The row goes after upstream's host and before Gentoo's distfiles, as each mirror row does, and names no
signature, as upstream publishes none.
…desktop.org does not answer: Void's source mirror, which keeps the same archive
…stream made since

Kernel currency's gate failed on both the branch's dispatched runs: rustc was reviewed to 1.99.0
and pkgconf to 3.0.8, and each upstream has released since. On a pull request the gate only
informs; on main's push it fails, so the browser push would turn main's Kernel currency red.

rustc 1.99.1 (2026-10-15) fixes three things: a miscompilation 1.99.0 brought in on x86-64, where a
function returning bool to C left the upper bits set because rustc stopped marking the return
zeroext (rust-lang/rust#163911); wcslen on UEFI and embedded targets; and rust-lld's rpath on
macOS. 1.98.1, the pin, still masks the bool. The row now says never 1.99.0.

pkgconf 3.0.9 (2026-10-15) is three commits: the Autotools build runs spdxtool's utility tests,
NEWS, and the version. No security advisory is published for either.
… answer: Void's and BLFS's copies of the same archives

Source reachability names wlroots 0.19.3 and libdrm 2.4.129 as served by their upstream alone,
gitlab.freedesktop.org's release download and dri.freedesktop.org, hosts that have failed cold
fetches before; Gentoo's distfiles keep neither file. A cold build stops at them.

Void Linux's source mirror keeps wlroots-0.19.3.tar.gz, 671,529 bytes with the lock's 5d026931..ccc5,
and BLFS's conglomeration on OSUOSL keeps libdrm-2.4.129.tar.xz, 433,392 bytes with the lock's
5978183f..77dc. Alpine's wlroots-0.19.3.tar.gz is another archive (a6ff89b6..), and Debian, Alpine
and Void keep no libdrm 2.4.129. Neither mirror keeps upstream's signature, so both rows name none,
as the Alpine wayland row does. Void names its package after the series (wlroots0.19), which a
comment says, as the row has to move with a series change.

libinput 1.30.4 stays its upstream's alone: no distribution keeps the GitLab archive of 1.30.4.
So they merge cleanly beside the block of mirror rows that goes in above the wayland rows.
…e, each checked against the lock

The probe of every place each source is kept found 51 sources that one place alone serves. These
rows give 25 of them another: the LFS 12.2 package set and BLFS's archive at OSUOSL, kernel.org's
and sourceware's mirrors, a nongnu mirror, metacpan and OSUOSL's CPAN, Kitware's GitHub releases,
and Debian's, Alpine's and Void's copies. Each file was downloaded on 2026-10-16 and has the lock's
SHA-256. No row claims upstream's signature.

libaio's own host, releases.pagure.org, answers 404 for its tarball today; only Gentoo's distfiles
served it.

A row in a fixed directory, LFS 12.2's set or util-linux's v2.42, lapses when the pin moves past it,
as a distribution's row does, and the fetch asks the next place.
Round 6's image-corrupt failed on wording alone: the flipped block did read as EIO, and kryptikd,
static musl, reported its exec of the probe as "I/O error (os error 5)", while the check looked for
glibc's "Input/output error". The next start was refused as signed.
Firefox's nsLocalFile::GetDiskSpaceAvailable asks the user's quota on the profile's device
(quotactl Q_GETQUOTA) from its network cache's thread, Cache2 I/O, a moment after it starts. The
zone filter killed it for that before a window showed: the audit line in the desktop suite's
browser-window failure reads syscall=179, comm "Cache2 I/O", exe /usr/lib/firefox/firefox. On any
failure Firefox keeps the free space statfs gave, so EPERM costs it nothing.

quotactl stays in the denied list, so no policy opens it: setting a quota is its other use. A unit
test holds both, and zone-policy-files.md says why.
…9 reviewed: neither is a security fix that reaches Kryptik
… own host served get a second place, each checked against the lock
…ted under /run/kryptik, and names any file it finds

Round 6 failed no-passphrase-leak with no passphrase anywhere: the search is grep -r over
/run/kryptik, and since personal and untrusted carry the browser and the toolkit, kryptikd keeps
their images mounted at /run/kryptik/images and their stacked sets at /run/kryptik/usr. The grep
walked Firefox's and GTK's whole trees, where a "dev-pass" in any file is a match.

A leaks helper searches the files under /run/kryptik with those two mounts pruned, and every
command line, through xargs and grep -l, so the check's failure names the files that matched,
never what they hold. The zones' roots are in mount namespaces of their own, so the host's
/run/kryptik holds the registry and the two image mounts alone: the search over the registry
and the command lines is unchanged.
… either C library's words, as kryptikd is static musl
…zone, not killed: Firefox's disk-space check reads the user's quota at start
…d images mounted under /run/kryptik, and a failure names the files that matched
@DevomB
DevomB marked this pull request as ready for review October 16, 2026 09:28
@DevomB
DevomB merged commit dfd4299 into main Oct 16, 2026
23 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant