Watch
1
0
Fork
You've already forked SouveraineOS
0

docs: correct three claims that were false, in place

START-HERE §6 said the phone has no wifi away from home because the
SSIDs are pinned. It joined a foreign SSID on 2026-08-02 and sat there
working while that paragraph sent the reader hunting for a cable. It
now says how to pass the address, and records that a phone off the home
net reaches the repo through the laptop rather than by bringing the
phone's tunnel up.

TASK-51 §3 said the volume buttons do nothing. They were wired on
2026-08-02 in 266af98 — Action::Volume on the down edge, through the
executor table, with tests. Only the gesture level is still unbound.

SECURITY-AUDIT gains three rows its own review cadence required: the
virtual-keyboard and input-method bind filters admit every client, which
is keystroke injection and observation from any uid-1000 process
(verified live with wtype); the clipboard gate is written and tested and
routed at no call site; xdg-activation accepts every token and never
prunes them.
This commit is contained in:
Fimeg 2026-08-03 15:31:56 -04:00
commit 5c9a652dfd
3 changed files with 62 additions and 11 deletions

View file

@ -163,8 +163,22 @@ ssh -i ~/.ssh/ani casey@10.10.20.234 # home wifi, via VPN
after a reboot. If gitea resolves to a Cloudflare address, the tunnel is down.
On the phone: `nmcli con up wiufph`. On the laptop: `wiufarch`.
Away from home the phone has no wifi — the SSIDs are pinned to the home network —
so USB is the only path, which is why §1 matters.
**The phone does join networks that are not home.** This page used to say it
could not — that away from home the SSIDs are pinned and USB is the only path.
On 2026-08-02 it sat on a foreign SSID at `10.10.30.213` working perfectly while
that paragraph sent the reader hunting for a cable. Pass the address:
```sh
Pixel3Arch/tools/phone-triage.sh 10.10.30.213 # or export PHONE_HOST
```
Find it from the router, or on the phone with `ip -br a show wlan0`.
**A phone on a foreign network cannot reach the package repo**, since that lives
at `10.10.20.120:4455` behind the VPN. You do not need to bring `wiufph` up for
that — the laptop has the tunnel and the phone is on the local subnet, so fetch
on the laptop and push down: gitea release → `scp``pacman -U`. Leave the
phone's tunnel alone; it is the user's switch.
---

View file

@ -137,6 +137,9 @@ Tracked gaps. Each has a status; none are silently accepted.
| Autonomous invisible capability use | Open — P3 not yet enforced | P3 |
| Cross-machine user-data sync (contacts federation) | Parked — separate trust domain | `contacts-design.md` |
| **Arbitrary signed TA loading from the AP** | **New 2026-08-01 — ungated beyond file perms** | below; TASK-44 |
| **Any uid-1000 client may inject and observe keystrokes** | **New 2026-08-03 — `virtual_keyboard` and `input_method` bind filters are `\|_\| true`** | below; TASK-41 |
| Clipboard gate is written and tested but routed nowhere | New 2026-08-03 — `Act::ReadClipboard`/`OfferClipboard` enforced at no call site | below; TASK-41 |
| xdg-activation accepts every token, and `known_tokens` never prunes | New 2026-08-03 | below; TASK-41 |
---
@ -177,6 +180,40 @@ attested to a caller, and *visible* when used (P3) — or whether root-only is
the accepted answer for a single-user device. Do not let "the fingerprint
needed it" become the implicit policy for every TA on the device.
## Three ungated boundaries in the compositor, found 2026-08-03
Recorded because two of them are keystrokes, and because the fix for one of them
is already written.
**`zwp_virtual_keyboard_v1` and `input-method` bind filters are `|_| true`.** Any
process running as uid 1000 may create a virtual keyboard and synthesize
keystrokes into whatever holds focus, or install itself as the input method and
observe what is typed. Verified live on the phone: `wtype "helloworld"` from an
ssh session landed in a terminal and was captured verbatim. That is an injector
and a keylogger from an unprivileged process, with nothing attesting the caller.
The usual ceiling argument does not cover this. Elsewhere the honest position is
"today's ceiling is what any uid-1000 process could already do by running
`blueline-screen-toggle`" — but blanking a screen is not reading a password, and
this is the first boundary where that comparison stops holding.
**The clipboard gate exists and is routed nowhere.** `gate.rs` defines
`Act::ReadClipboard` and `Act::OfferClipboard` and carries a written, tested
refusal policy for them — no client reads the clipboard behind a lock screen.
Neither variant is referenced at any call site. `Act::Capture` and
`Act::DeliverInput` *are* routed, so the seam works; these two simply never got
connected. This is the cheaper and better-designed half of the fix: route the
existing verdicts rather than invent a bind-time mechanism, since a bind filter
decides once and the gate can refuse per action with the lock state in hand.
**xdg-activation accepts every token and `known_tokens` never prunes.** The code
comment already groups it with the two filters above. An unbounded set that
nothing evicts is its own problem, separate from who may create entries in it.
All three are TASK-41's scope, and the standing rule there is that attestation
lands at every boundary or none — so a fix that closes the loud two and leaves
activation open has not closed anything.
## Long-arc goal — process isolation + integrity monitoring
**Goal:** isolate every process into a known, gated section, with a Wazush-style

View file

@ -43,17 +43,17 @@ scene a second time off-screen rather than reading the scanout buffer, and that
reason is worth preserving: handing a client a mapping of the swapchain also
hands it whatever the next frame's allocation reuses.
## 3. Volume buttons do nothing
## 3. Volume buttons — DONE 2026-08-02 (`266af98`)
viewtop reports `VolumeUp`/`VolumeDown` edges to sessiond and the daemon
recognises them — `apply_gesture` binds **only** power-tap, so the gesture is
recognised and dropped. Under Hyprland these were `wpctl` calls in
`hyprland.lua`. They are the second-most-used control on the device.
`Action::Volume` is pushed on the button **down** edge (`device_state.rs`) and
executed through sessiond's executor table (`server.rs`), with tests. It went
the way §12 required — an `Action`, not a shell-out from the compositor — and
acts on the press rather than on a recognised gesture, because the multi-tap
window would otherwise put 300 ms between the press and the sound changing.
The shape is settled by §12's argument (an Action, not a daemon) and by
TASK-39: audio belongs in the state machine as state, so this wants
`Action::Volume(..)` through the executor table rather than a shell-out from
the compositor. **Do not** wire it in viewtop — that is the eighth blind actor.
Still unbound: the *gesture* level. The recogniser resolves volume taps and
holds from the same edges, so hold-to-ramp or double-tap costs a binding rather
than a mechanism. That is where the Activator-shaped binding table lands.
## 4. `furniture_at()` returns `None`