Two security improvements to redbear-notifications:
1. InvokeAction sender + ID + action_key validation.
Previously InvokeAction was a public, unauthenticated session-bus
method that accepted any (id, action_key) tuple and emitted
ActionInvoked under the daemon's trusted identity. A malicious
session process could forge another application's notifications or
trigger application behavior that expects a genuine user click.
Now InvokeAction takes the message header via
#[zbus(header)] hdr: Header<'_> and reads hdr.sender(). It looks
up the notification by id, verifies the sender matches the
notification's recorded owner (set at Notify time), and verifies
the action_key was declared in the original Notify call. Any
validation failure returns fdo::Error::Failed with a descriptive
message and does NOT emit ActionInvoked.
2. Active-notification tracking.
Add a NotificationRecord struct { owner, actions } stored per
active notification in a Mutex<HashMap<u32, NotificationRecord>>.
Notify() now inserts the record and tracks the sender. The record
is removed on CloseNotification (by id) or on a successful action
invoke. Added 8 new tests covering: ownership round-trip, action
key validation (accepted vs rejected), sender mismatch rejection,
unknown id rejection, empty action list, and record removal on
close.
Verified: 16/16 notifications tests pass (8 new + 8 existing).
The redbear-wifictl NM-shaped D-Bus interface returned wire-incompatible
types that no compliant client (Qt, GNOME, kf6-networkmanager-qt) could
parse:
1. Root State returned a NmDeviceState value (up to 120 = Failed),
but Qt's qnetworkmanagerservice.h:65-74 defines NmState as
0..=70 (Unknown..ConnectedGlobal). Returning a device-state value
in the manager-state property is wire-incompatible.
2. get_devices() and get_access_points() returned Vec<String>, but
the D-Bus spec requires Vec<o> (array of object paths). zbus
serializes Vec<String> as 'as' which clients reject.
3. active_access_point returned String, should be o. The sentinel
'/' for 'no active AP' is a valid object path per spec.
Fixes:
- Add new NmState enum with the correct 8 variants (Unknown=0,
Asleep=10, Disconnected=20, Disconnecting=30, Connecting=40,
ConnectedLocal=50, ConnectedSite=60, ConnectedGlobal=70).
- Add NmState::from_device_state(NmDeviceState) mapping table:
Unmanaged/Unavailable/Disconnected/Failed -> Disconnected;
Prepare/Config/NeedAuth/IpConfig/IpCheck -> Connecting;
Activated -> ConnectedGlobal; Unknown -> Unknown.
- Root state property now returns NmState::from_device_state(
device.state).as_u32(), guaranteed 0..=70.
- get_devices(), get_all_devices(), active_connections (property),
get_access_points(), get_all_access_points() all return
Vec<OwnedObjectPath> via a shared try_path() helper that maps
malformed strings to fdo::Error::Failed instead of panicking.
- active_access_point() property returns fdo::Result<OwnedObjectPath>;
uses '/' sentinel when no AP is active.
- 5 new host tests verify NmState numeric values (the Qt-required
0/10/20/.../70 sequence), from_device_state mapping, and the
'range never exceeds 70' invariant.
Verified: 35 unit + 2 integration tests pass.
Three related fixes for redbear-sessiond and redbear-statusnotifierwatcher:
1. StatusNotifierWatcher: change well-known D-Bus name from
'org.freedesktop.StatusNotifierWatcher' to 'org.kde.StatusNotifierWatcher'.
Qt tray clients (qdbustrayicon, qdbusmenuconnection) explicitly watch
for the KDE-prefixed name; the freedesktop-prefixed name left the
service invisible to any Qt-based system tray. Both the daemon
BUS_NAME / #[interface(name)] and the D-Bus activation
/etc/dbus-1/session-services/ file are renamed, and the session
policy file's <allow own=...> entry is updated. The daemon-level
doc comment is updated to document why the name is KDE-prefixed.
2. sessiond: replace host-dependent can_methods_return_na test.
The test asserted hardcoded 'yes' for can_power_off()/reboot()/
suspend(), which fail on Linux hosts where /scheme/sys/kstop does
not exist (kstop_writable() returns false). Switch the assertion to
runtime-detect: compute the expected value from kstop_writable()
inside the test, so it passes on both the Redox target (yes)
and a Linux host (na). All 52 sessiond tests now pass on host.
3. sessiond: implement inhibitor lifecycle reaping.
Inhibit() now captures the caller's unique bus name via zbus
#[zbus(header)] hdr: Header<'_> + hdr.sender(). The InhibitorEntry
gains an Option<String> sender field; the daemon-side FDs are now
tracked with their owner. set_connection() spawns a background
task that subscribes to org.freedesktop.DBus.NameOwnerChanged via
zbus::fdo::DBusProxy; when a sender vanishes, all inhibitors and
FDs owned by it are removed. list_inhibitors() defensively filters
out entries with dead senders. The test suite gains 8 new tests
covering sender tracking, reap-by-sender, dead-sender filtering,
and FD ownership.
Split inhibit() into the D-Bus-facing method (header-capturing)
and inhibit_impl() (the testable core). Tests call inhibit_impl
directly with an explicit sender argument.
Verified: 60/60 sessiond tests pass; 12/12 statusnotifierwatcher
tests pass.
The batch BO pool in redox_drm_cs.c had three memory-safety bugs:
1. Class math: the pool is documented to cover 'sizes 4 KiB to 512
KiB' across REDOX_DRM_BATCH_POOL_SIZE_CLASSES (8) slots, but the
implementation computed the class as ceil(log2(byte_count)) from the
raw byte count without applying the 4 KiB base. A 32 KiB batch
request (which should map to class 3) ended up at class 15, which
is >= 8, so the pool returned NULL and every GPU submission
allocated a fresh BO — the pool was completely non-functional.
2. Undersized cached BOs: the BO was allocated with width0 = byte_count
(exact request size) but cached against a class index that expected
the full class capacity. A subsequent request that mapped to the
same class but with a larger byte_count could receive a BO smaller
than the write and silently overflow the heap.
3. No synchronization: the pool was shared across pipe_contexts but
accessed without any mutex — concurrent submissions from multiple
threads would race on rws->batch_pool[cls].
4. Resource leak: batch_bo_release returned silently if the entry
couldn't be cached, leaking the BO.
Fixes:
- Replace the per-call class math with a shared helper
batch_bo_size_class() that returns cls = log2_ceil(byte_count) - 12
(with clamping for sub-4-KiB requests). Oversized requests return
REDOX_DRM_BATCH_POOL_SIZE_CLASSES to signal 'fresh allocation, not
pool'.
- Add batch_bo_class_capacity() returning 4096 << cls.
- Acquire now allocates BO at the full class capacity (not the request
size), so any cached entry can serve any smaller request in the
same class on recycle.
- Acquire defensively verifies width0 >= byte_count before returning
a cached entry; undersized entries are destroyed.
- Release destroys entries that don't match the class capacity, and
destroys redundant entries when a slot is already occupied (rather
than leaking).
- Pool is guarded by a new mtx_t batch_pool_mutex field on
redox_drm_winsys (initialized in redox_drm_initialize, destroyed
in redox_drm_destroy).
The related 'format = 0 -> 0-byte GEM object' issue in
redox_resource_byte_count is a separate bug (batches need a non-NONE
format to get real storage); tracked as a follow-up.
Verified by a standalone host gcc test of the class math covering 15
boundary cases (0, 1, 4096, 4097, 8192, 32768, 524288, 524289,
1048576, etc.); all match expected class assignments.
Round 16 audit follow-up. Three small fixes:
1. local/recipes/system/redbear-authd/source/src/main.rs:328 — the
validation-mode spawn-reaper thread did 'let _ = child.wait();'
silently dropping the session child's exit status. Replaced with
'match' that eprintln-logs both successful exit status and wait
failure (with errno). Operators can now see when the session
child exits abnormally in validation mode.
2. local/recipes/system/redbear-dnsd/source/src/main.rs:111 — the
loopback DNS responder did 'let _ = socket.send_to(&reply, &src);'
silently. Replaced with 'if let Err(e) = socket.send_to(...)' that
eprintln-logs the failure with the source peer address. Previously
DNS clients could fail to receive a valid reply with no visible
error.
3. local/docs/SUPERSEDED-DOC-LOG.md — appended Round 16 entries
documenting the authd/dnsd fixes plus the Round-16 audit findings
that did not require code changes (acpi-rs AML 41 panics classified
as internal-invariant, pcid panics already have messages, all stale
CONFIG refs already retired, USB-daemon let _ = is in host-only test
paths, sessiond can_* for sleep is honest stub, Mesa CS ioctl
numbers verified no drift).
3 files changed, +27/-2.
Round 16 audit follow-up. Two small but useful additions:
1. local/docs/SUPERSEDED-DOC-LOG.md — appended R15 entries:
greeter/netctl/hotplugd let-underscore-to-logged (5682072e58),
acmd setrens security fix (883e8147ec), README null+8 contradiction
reconciliation, and the redbear-live.iso stale-reference fix.
2. local/recipes/system/redbear-sessiond/source/src/manager.rs —
the can_hibernate / can_hybrid_sleep / can_suspend_then_hibernate
/ can_sleep functions all return hardcoded 'na'. Documented the
integration plan in a block comment above them: when the
/scheme/sys/sleep and /scheme/sys/hybrid_sleep schemes exist
in the Redox kernel, replace these with fs::metadata() probes
matching the kstop_writable() pattern used by
can_power_off/can_reboot/can_suspend. No code change yet —
just the docstring pointing the next maintainer at the pattern.
Without this comment, a future maintainer reading the four
hardcoded 'na' returns would not know about the kstop_writable
probe pattern that enables the matching sleep capabilities.
2 files changed, +32/-5.
Updates the canonical current-state doc to reflect the Round-5
deliverables:
- "Last updated" header bumped to
"F1-F6d fixes + Round-5 N17+N18".
- § 5.10.3 Round-5 summary section added (cross-references
the new code-audit doc).
- § 6.5 per-fix summary table extended with the 4 N18 driver-
manager bug fixes (Q1, Q2+Bug4, S3, Bug5) and a row pointing
to the new `DRIVER-MANAGER-CODE-AUDIT-2026-07-27.md` for
the full audit context.
- § 7.1 References updated to list the new code-audit doc as
the primary Round-5 internal reference.
Three changes in scheme.rs:
- Add `self_weak: Mutex<Option<Weak<DriverManagerScheme>>>` field
to the `DriverManagerScheme` struct (cfg-gated on redox, the
same pattern as the existing `handles`/`modalias_results`
fields).
- Add `set_self_weak` method that stores a `Weak`
self-reference; main.rs calls it with
`Arc::downgrade(&scheme)` after `set_manager`.
- Replace the `reset_device` arm of `dispatch_recovery`
with a detached worker that captures the manager Arc + the
scheme Weak, runs `remove_device` → `sleep 100 ms` →
`bind_device` on the worker thread, and notifies the
scheme of the rebind events via `self_weak.upgrade()`. The
scheme server thread is no longer blocked for 100 ms during
recovery; the endpoint stays responsive.
Includes a warning if `self_weak` is unset, the manager
isn't set, or the worker thread fails to launch (graceful
no-op rather than panic).
Two changes in one file:
- Q2 mechanical: change the spawn_reaper_thread closure
signature from `Fn(u32)` to `Fn(u32, i32)`; capture
`waitpid` status via `&mut status`; pass both `res` and
`status` to the reaper callback. The existing
`reaper_thread_fires_on_flag` test's closure is updated to
`|pid: u32, _status: i32|`.
- Bug5: `run_watchdog` no longer silently `return;`s on a
reaper thread panic. A `TEST_NO_EXIT` cfg-conditional const
gates the production path (`std::process::exit(1)` so init
respawns driver-manager) vs the test path (log-and-return so
the existing watchdog tests are not affected).
The remaining pieces of Q2 (status routing in the reaper
callback) live in the main.rs Q1+Q2+S3 commit.
Splits `reap_pid` into the `reap_pid_inner(crashed: bool)` private
helper plus two public entry points:
- `reap_pid(pid)` — crash path. Calls
`crash_tracker().record_failure` after the maps are cleared,
which advances the auto-blacklist counter.
- `reap_pid_clean(pid)` — clean exit path. Calls
`crash_tracker().record_success` so the device's backoff is
reset; a future crash starts the count from 1, not from
where the previous clean-exit backoff ended.
Both paths also call `error_channel::global().remove(&key)` to
close the sidecar UnixStream fd (Bug4: each crash previously
leaked one fd; ~1024 crashes exhausted the manager's fd table).
This is the kernel of N18-Q2+Bug4; the call-site change in
`main.rs` that interprets the waitpid status was committed in
the prior Q1+Q2+S3 commit.
Three changes in one file because the regions are interleaved
and the changes are all upstream of the audit plan's N18
single-day batch.
- Q1: `main.rs:636-661` rewritten to build one
`Vec<Arc<DriverConfig>>` and pass `Arc::clone` to both
`DeviceManager` via the new `register_driver_shared` and
to the reaper registry via `Arc::downgrade`. Removes the dead
`registry_configs` second-loop block.
- Q2: reaper closure at `main.rs:765-772` interprets
`waitpid` status via `WIFEXITED && WEXITSTATUS == 0` or
`WIFSIGNALED && WTERMSIG in (SIGTERM, SIGINT)` as a clean
exit, routing to `reap_pid_clean`; anything else routes to
`reap_pid` (crash).
- S3: cfg-gated `set_self_weak(Arc::downgrade(&scheme))`
call after `set_manager` so the detached AER recovery
worker can notify the scheme of rebind events.
driver-manager tests: 164 passing (no regression).
Adds an additive `register_driver_shared(Arc<dyn Driver>)` method
to `DeviceManager` so the caller (driver-manager) can pass a
pre-shared `Arc<DriverConfig>` and retain a `Weak` reference
to the SAME allocation. The SIGCHLD reaper's `Weak::upgrade()`
then resolves to the same maps that `probe()` populates, fixing
the long-standing Q1 dead-driver-leak where the reaper operated
on stale clones with empty maps.
Consolidates 4 prior code-level review agents for the
driver-manager subsystem: 2 CRITICAL (reaper-clone, every-exit-
as-crash), 3 HIGH (scheme 100 ms block, reap_pid error_channel
fd leak, watchdog-exit-on-panic), ~10 MEDIUM, ~11 LOW with
file:line refs and planned-fix table. Companion to
DRIVER-MANAGER.md; no source or recipe changes.
Three doc/code fixes from the Round 15 audit:
1. redbear-acmd setrens security: the bare 'let _ = setrens(0,0)'
silently dropped the syscall result. If setrens failed the
CDC-ACM daemon would retain its original namespace and serve
USB-serial requests with potentially elevated privileges. Now
logs the error and returns early so the daemon refuses to
serve with unknown namespace rather than continuing degraded.
2. README.md null+8 contradiction: line 138 used ✅ (implying
fixed) while lines 140/143/144 used 🟡 'runtime blocked'. Both
could not be true. Demoted line 138 to 🟡 with caveat about
compile-time guards only and runtime re-verification pending,
matching QT6-WAYLAND-NULL8-DIAGNOSIS.md status. The four
lines now agree.
3. README.md + AGENTS.md: replaced the non-existent config
'redbear-live' (with output 'redbear-live.iso') with the
accurate '<config>.iso' pattern. No 'redbear-live' config
exists; ISO outputs follow '<config>.iso'.
Also fixed README.md plan-version date from 2026-07-26 to
2026-07-27 to match CONSOLE-TO-KDE-DESKTOP-PLAN.md.
3 files changed, +12/-6.
Round 15 audit cleanup. Three production paths were discarding
process / filesystem errors via bare 'let _ = ...'. Each silently
swallowed the error and the caller had no way to know the cleanup
failed — leading to zombie children (greeter), stale active-profile
symlinks (netctl), or unreaped USB device drivers (hotplugd).
1. local/recipes/system/redbear-greeter/source/src/main.rs — the
kill_child() helper now logs on kill() and wait() failure (with
debug-level success log) instead of 'let _ = process.kill();
let _ = process.wait();'. A failing kill() now produces an
eprintln so the operator sees it; wait() outcome is logged
at debug level.
2. local/recipes/system/redbear-netctl/source/src/main.rs — both
'let _ = fs::remove_file(active_profile_path());' sites (line 201
in stop_profile and line 224 in disable_profile) now log on
failure via eprintln. A failed remove_file previously left a
dangling 'active' symlink that subsequent boot would re-activate
silently.
3. local/recipes/system/redbear-usb-hotplugd/source/src/main.rs —
the 'if let Some(ref mut child) = dev.child { let _ = child.kill(); }'
in the disconnect path now logs on kill() failure (log::warn) so
a leaked USB driver child produces a visible warning.
Found by the Round 14 audit (local/docs/3D-DESKTOP-COMPREHENSIVE-PLAN.md §10).
Round 14 audit cleanup. Six coordinated fixes across seven files
plus a documentation log update:
1. local/recipes/system/redbear-wayland-guard/ — REMOVED entirely.
The directory contained only source/wayland_guard.c — an LD_PRELOAD
interposer stub for three wl_proxy_* functions — with NO recipe.toml.
This violated local/AGENTS.md STUB AND WORKAROUND POLICY ('No LD_PRELOAD
tricks'). The correct null-guard fix lives in libwayland upstream per
QT6-WAYLAND-NULL8-DIAGNOSIS.md (already covered by Mesa win compat).
2. recipes/system/redbear-wayland-guard — broken symlink cleaned up.
3. local/recipes/AGENTS.md — catalog entry for redbear-wayland-guard was
wrong (claimed 'Rust' but the code was C LD_PRELOAD). Replaced with
REMOVED note explaining the policy violation and the correct fix
location in libwayland.
4. local/recipes/system/firmware-loader/source/src/main.rs — converted
9 .expect() calls in the daemon init path (Socket::create, scheme_root,
create_this_scheme_fd, syscall::call_wo notify, setrens, next_request,
write_response) to Result propagation. get_init_notify_fd() and
notify_scheme_ready() now return Result; run_daemon() returns Result and
main() matches on Err to log+exit(1) cleanly. The daemon was
crashing the entire firmware-delivery subsystem on any init failure;
now init can fall back or restart the daemon.
5. local/recipes/system/{redbear-keymapd,redbear-ime,redbear-accessibility}/
source/src/main.rs — three scheme daemons used the same
Socket::create().expect() + register_sync_scheme().expect() pattern.
Replaced all six .expect() calls with match expressions that
log_msg('ERROR', ...) and process::exit(1). Same pattern.
6. local/docs/NETWORKING-AND-DRIVERS-SYSTEMATIC-ASSESSMENT-2026-07-27.md —
struck through 5 references to the now-removed redbear-wayland-guard
(line 65 missing-daemons list, line 344 table row, line 397
implementation list, line 414 source-list, line 797 P3-8 backlog).
7. local/docs/SUPERSEDED-DOC-LOG.md — appended a 'Rounds 11-14 Source-Level
Supersessions' table logging every lie-grade fix and stale-doc
strike from this session. Mirrors the original deletion-log style for
consistency, and gives operators a single place to see what was
resolved and where. Documents the emerging pattern: lie-grade code in
Red Bear concentrates in (a) relibc panic-site catch-alls (addressed
rounds 9-10), (b) scheme daemon init paths using .expect() instead of
Result (rounds 11-14), (c) Mesa DRM/Wayland stubbing (rounds 12;
remaining work tracked in 3D-DESKTOP-COMPREHENSIVE-PLAN.md).
Not committed in this commit (operator's parallel work, to be
committed by them):
- driver-manager/* (N-tier edits)
- redbear-sessiond/manager.rs (can_* probe refinements)
- redbear-statusnotifierwatcher/* (recipe + source)
- redbear-dbus-services/* (dbus service cleanup)
- redox-driver-core/manager.rs (test-only)
- Mesa redox_drm_cs.c (CS submit fix)
7 files changed in this commit + 2 deletions.
Commit 222d5186eb ('add minimal # Safety comments to 70 files')
inserted a '// SAFETY: ...' line mid-token in backend.rs:1405,
splitting 'perms.set_mode(0o755);' into 'perms.set_mo' + comment +
'de(0o755);'. The result is a compilation error that prevents the
entire redbear-wifictl crate from building — including the new
dbus_nm.rs interface from e65a23fd6b.
Restore the single-line call. The Safety rationale is captured by
the surrounding cfg(unix) block.
Verified: cargo check --features dbus-nm compiles, 35 unit tests
+ 2 cli_transport pass.
The Round 11 commit (a9e1c34e27) fixed both findings 14/15 and
18/18b/19 in the assessment doc; the Round 11 fix and Round 12
follow-ups (this round) update the remaining stale references.
1. local/docs/3D-DESKTOP-COMPREHENSIVE-PLAN.md §10 config table
(lines 1159-1160): marked wifi-experimental.toml and
bluetooth-experimental.toml include-typo as ✅ FIXED 2026-07-27
(was still listed as open).
2. local/docs/NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md:
struck through:
- Finding 15 (redbear-passwd missing [source])
- Critical-path P0-12/13/14 (include typo + [source] todo)
- The Critical Path Hierarchy bullet list items
- TODO priority list line 718 (redbear-passwd [source])
- Backlog line 923 (C-23)
Marked each with ✅ RESOLVED 2026-07-27 (commit a9e1c34e27).
These were the last unstruck-through references after the
Round 11 fix landed. The assessment doc is now consistent
with the post-fix state.
2 files changed, +14/-12.
Submodule local/sources/base updated to c5b32f9f, which replaces
three production panic sites with proper error handling: vesad's
bare panic!() at loop exit, nvmed's timeout panic, and two
commented-out NVMe queue-error panics.
Bumps local/sources/base to include the three BufferPool F001
regression tests added in the previous commit. These tests document
the expected zero-fill behavior and serve as a regression net for
any future change to the BufferPool recycling path.
Companion to the prior 'address 5-lane review blocking findings' commit
(which only contained the restored dbus symlink). This commit bundles the
remaining review-driven fixes for the implementation scope.
- sessiond power_off/reboot/suspend: propagate write_all errors. The
'let _ = f.write_all(...)' pattern meant a successful open followed
by a failed write was reported to the caller as success. Now checked
with explicit error propagation: write failure resets
preparing_for_shutdown/sleep to false and returns a D-Bus error.
- notifications: drop un-implemented capability advertisement
('actions', 'persistence'). Real capabilities now: ['body', 'body-markup'].
Body and app_name no longer printed to stderr verbatim (length only).
Server info version bumped 0.3.0 -> 0.3.1 to match Cargo.toml.
- wifictl: enable dbus-nm feature by default. Previously
default = [] made the 656-line NM interface dead code behind a
feature gate that the recipe never enabled.
- guard-recipes.sh --restore: add parent-symlink guard (same as --fix).
Without it, restoring a recipe whose parent directory is a symlink
into local/recipes/ deletes the real file from disk.
- verify-fork-functions.sh: narrow blanket exclusion to fmt+eq only.
drop/deref/hash/clone/etc. must go through fork-specific exclude file.
Verified:
redbear-notifications: 8/8 tests pass
redbear-sessiond: 51/52 tests pass (1 pre-existing failure
from later commit a9e1c34e27 outside scope)
redbear-wifictl: compiles with dbus-nm default
§15.3 had a contradiction: the table at line 1065 listed items as
'Remaining' that were already marked DONE in §15.1 and in the
commit history. This was a documentation hazard - an operator
reading §15.3 would waste time chasing already-fixed bugs.
Update the CRITICAL row to reflect the actual current state:
- Added explicit notes on completed this-round refinements
(BufferPool v.resize completion, xHCI snapshot-before-clear,
IPv6 final-protocol+offset+AH-formula fixes, F002 RawFd,
F003 redundant cast, TCP call() override, getsockopt
todo_skip removal)
- Updated HIGH row similarly (TCP SendMsg, MSG_NOSIGNAL,
relibc option level collision now marked DONE)
§15.3 now accurately reflects the current state of the
implementation effort.
The 5-lane review of the 3 implementation commits uncovered
several actionable items in the scope of those commits. This
follow-up fixes the critical ones.
1. guard-recipes.sh --restore: add parent-symlink guard
The --restore mode was missing the parent-symlink guard that
--fix mode has. Without it, a recipe whose parent directory is
a symlink into local/recipes/ could be deleted from disk during
restore (the file symlink resolves through the dir symlink, so
the subsequent rm -f deletes the real local file). This was a
CRITICAL data-loss vector.
2. dbus-root-uid.patch symlink: restore
The commit e65a23fd6b deleted this symlink as 'orphan cleanup'
but recipe.toml still references it in its patches list.
Without the symlink, the next clean fetch of the dbus recipe
would fail with 'Failed to find patch file'. Restored.
3. wifictl dbus-nm feature: enable by default
The 656-line NM interface implementation was feature-gated
behind dbus-nm with default = [], making it dead code at
build time. This violates the zero-stubs policy (no
feature-gated no-ops). Changed default to ['dbus-nm'] so
the interface is actually wired in the built binary.
4. redbear-sessiond power operations: propagate write_all errors
power_off/reboot/suspend were discarding write_all results
with 'let _ = ...'. A successful open followed by a failed
write was reported to the caller as success. Now the write
result is checked and reported as a D-Bus error, with
preparing_for_shutdown/sleep reset to false on failure.
5. redbear-notifications capabilities: stop advertising unimplemented features
The capabilities list advertised 'actions' and 'persistence'
but the implementation has no graphical UI for action rendering
and does not persist notifications across daemon restarts.
Honest capabilities now: ['body', 'body-markup']. Also
sanitized notification body logging (no body, app_name, or
summary in stderr to avoid data exposure); updated server
information version string from 0.3.0 to 0.3.1 to match
the actual source Cargo.toml.
6. verify-fork-functions.sh: narrow blanket exclusion
The blanket exemption covered drop, deref, hash, clone,
and other methods that can carry custom semantics. The
exemption now covers only fmt and eq (derivable, no semantic
cost). All other trait methods must go through the
fork-specific .verify-fork-functions.exclude file.
Out of scope (pre-existing, not from the reviewed commits):
- sessiond 'can_methods_return_na' test failure on Linux host
(caused by kstop_writable() probe added in later commit a9e1c34e27)
- wifictl backend.rs compilation corruption from later commit
222d5186eb ('add minimal # Safety comments to 70 files'
split perms.set_mode(0o755); mid-token)
- AI co-author attribution in submodule/base commit ec7670ef
(cannot rewrite history per AGENTS.md no-force-push rule)
Round 12 audit cleanup. Five fixes across five files plus a
zero-tolerance stub policy win:
1. local/patches/mesa/04-sys-ioccom-stub-header.patch — DELETED.
The patch was a hand-rolled include/sys/ioccom.h with Linux IOC
bitfield constants, living as a Mesa-side stub. Per local/AGENTS.md
zero-tolerance policy: 'Any stub found in the tree is a bug to
be fixed, not a precedent to follow.' relibc's new
include/sys/ioccom.h (commit ca7a7edb on submodule/relibc,
bumped in f145e9e768) provides the same constants natively,
making the patch redundant.
2. local/recipes/libs/mesa/recipe.toml — removed the now-dead
'04-sys-ioccom-stub-header.patch' entry from the patches list.
Note added explaining the removal so a future maintainer does
not re-add it.
3. local/recipes/system/udev-shim/source/src/naming.rs —
predictable_net_name() used to return the hardcoded 'eth0' on
parse failure of the PCI address. On multi-interface systems
where multiple devices had unparseable PCI addresses, all
collided on 'eth0'. Now returns 'net-malformed-<sanitized>'
(unique per PCI string) so each device gets a distinct name.
4. local/sources/base/netstack/src/scheme/netcfg/mod.rs — the
'summary' branch hardcoded devices.borrow().get("eth0") which
made the summary output invisible to non-eth0 interfaces.
Now iterates the full devices map and prints each interface's
state. (The deeper 'ifaces' routing tree still has 20+ eth0
references — restructuring that requires a schema change;
deferred to a follow-up that adds a configurable default iface.)
5. local/docs/CONSOLE-TO-KDE-DESKTOP-PLAN.md + 3D-DESKTOP-COMPREHENSIVE-PLAN.md
— renamed 'redbear-kde-session' → 'redbear-session-launch' in the
final stale reference; clarified 'redbear-wayland.desktop' (not
yet wired).
Deferred: acpi-rs AML interpreter bare panic() (34 sites across
mod.rs) and netcfg ifaces routing tree (20+ eth0 references)
require schema-level refactors beyond one-shot fixes; tracked
for follow-up rounds.
Bumps both submodules to include:
- relibc: getsockopt forwards (level, name) for non-SOL_SOCKET levels
instead of stubbing with todo_skip!
- base: xHCI event TRB snapshot before clearing live DMA entry (F1.1
re-entrancy fix completed)
Submodule local/sources/relibc updated to ca7a7edb, which adds
include/sys/ioccom.h — a hand-written header providing Linux-style
ioctl command encoding constants (_IOC_NRBITS, _IOC_TYPEMASK,
_IOC_DIRSHIFT, _IOC_TYPECHECK, _IOC_DIR/TYPE/NR/SIZE decoders,
IOC_IN/OUT/INOUT, IOCSIZE_*) on top of the musl-style _IOC/_IO/
_IOR/_IOW/_IOWR macros that cbindgen already provides in
<sys/ioctl.h>.
DRM UAPI headers include <sys/ioccom.h> as the BSD naming path
for ioctl encoding. With this header in place, the Mesa-side
04-sys-ioccom-stub-header.patch becomes redundant and can be
removed (next commit).
N13 updates the policy.rs module docstring to reflect the four
current policy surfaces (blacklist + options + autoload + initfs-
manifest) and the active redbear-driver-policy state. Drops the
"before v1.4 the policy was dormant" stale reference.
N14 removes the remaining "previously marked as dormant" stale
comment in main.rs (now describes the four-count summary as
confirming the redbear-driver-policy package's curated config files
are wired). Simplifies the redbear-driver-policy README's
historical-dormant note to a single sentence about the cutover
date.
N15 — no stale doc removals needed: the 2026-07-27 doc
consolidation (recorded in SUPERSEDED-DOC-LOG.md) already
removed all known-stale docs. The 3D-DESKTOP-COMPREHENSIVE-PLAN
explicitly designates the two remaining NETWORKING assessment
files as operator-authored authoritative docs, so this round
does not delete them.
DRIVER-MANAGER.md adds § 5.10.3 Round-4 (N13–N15) summary.
164 driver-manager tests pass.
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
Bumps local/sources/base to include the RawFd call-site fix in
corec12_integration.rs and the complete BufferPool zero-fill
replacement of v.fill(0)+set_len(capacity) with safe v.resize(capacity, 0).
Both were review-identified blocking defects.
Submodule local/sources/relibc updated to 688e76ca, which clarifies
the misleading 'riscv64 and x86' message on the cfg-gated
unimplemented!() in do_tlsdesc_reloc. The gate correctly excludes
x86_64 and aarch64; the message now matches the actual reach (only
riscv64 fires).
Round 11 audit cleanup. Six fixes across six files:
1. local/recipes/system/redbear-passwd/recipe.toml — CRITICAL: was
missing the [source] block entirely. The recipe had only [package]
and [build] with template=cargo, which the cookbook cannot fetch.
Added [source] path = "source" so the cookbook locates the local
Rust crate. Also added a one-line description.
2. local/recipes/dev/libclc/recipe.toml — MEDIUM: the build script
installs via cmake but never verifies that libclc.pc (Mesa's
pkg-config dependency) and the .bc bitcode files actually landed.
Without these, Mesa's 3D driver cook fails opaquely with
'Dependency libclc not found (tried pkg-config)'. Added three
post-install test -f checks that fail the build with a precise
error pointing at the missing path.
3. local/recipes/system/redbear-sessiond/source/src/manager.rs — HIGH:
the D-Bus login1 can_power_off / can_reboot / can_suspend methods
were returning 'yes' unconditionally — the archetype lie-grade-ok
pattern (probe says success, then the real action fails because
/scheme/sys/kstop is missing). Replaced with a kstop_writable()
probe that fs::metadata()s the path. Used metadata() rather than
an actual write because writing 'shutdown'/'reset'/'s3' to
/scheme/sys/kstop would trigger the action. The actual power_off/
reboot/suspend methods still report granular errors when the
write is refused.
4. local/recipes/system/redbear-dnsd/source/src/transport.rs — MEDIUM:
UpstreamConfig::default() hardcoded 8.8.8.8 + 1.1.1.1 as fallback
upstream DNS. Hardcoding third-party DNS bypasses netcfg integration
and leaks user queries without consent on first boot. Replaced with
an empty Vec — main() reads the upstream list from netcfg before
any query is dispatched; upstream queries SERVFAIL until netcfg
populates the list (honest default).
5. local/docs/GREETER-LOGIN-IMPLEMENTATION-PLAN.md — MEDIUM: 16
references to the non-existent binary 'redbear-kde-session' (now
'redbear-session-launch'). Global s/redbear-kde-session/redbear-
session-launch/g. Also updated two 'redbear-kde' profile-name
references to reflect the 2026-07-24 retirement and the current
'redbear-full' ownership of the desktop path.
6. local/docs/DBUS-INTEGRATION-PLAN.md — LOW: 7 references to
'redbear-kde-session' renamed to 'redbear-session-launch' (same
binary rename).
6 files changed, +68/-28.
Note: Mesa 04-sys-ioccom-stub-header.patch migration to relibc proper
(sys/ioccom.h with Linux-style IOC encoding) is deferred — the
patch is a genuine gap-filler (relibc's sys/ioctl.h has the basic
macros but sys/ioccom.h is the BSD include path DRM UAPI expects).
That work belongs in the relibc fork with a prefix rebuild and
should be coordinated with the operator's prefix-staleness policy.
Submodule local/sources/relibc updated to 90168f56, which converts
two panic-site unimplemented!() calls in the dynamic linker
(ld_so/dso.rs static_relocate and lazy_relocate) into proper
Err() returns. Executables using unfamiliar relocation types
now fail gracefully at dlopen time instead of aborting the
process.
See submodule commit message for full rationale.
Round 10 audit cleanup. Six fixes across nine files:
1. config/redbear-netctl.toml: stale comment referenced three
non-existent configs (redbear-minimal, redbear-desktop,
redbear-kde). Replaced with accurate include-chain note.
2. scripts/run.sh, build.sh, scripts/fetch-all-sources.sh:
replaced all 'redbear-minimal' references with the actual
canonical config names (redbear-mini, redbear-grub,
redbear-wifi-experimental, redbear-bluetooth-experimental).
Three previously listed configs (redbear-kde, redbear-live,
redbear-wayland) never existed; removed them from the loop
that preflights/scans/fetches 'ALL_CONFIGS' so those broken
references no longer abort the script.
3. local/recipes/wayland/xwayland/recipe.toml:
- removed stale '#TODO wayland-client, fix linux/input,
wayland-scanner shim' (the workarounds are now real fixes).
- added redbear-input-headers to dependencies so the
uncommented <linux/input.h> include in xwayland-input.c
resolves via Red Bear's in-tree input-headers recipe
(per local/AGENTS.md LINUX KERNEL SOURCE POLICY).
4. local/recipes/wayland/xwayland/redox.patch:
- stripped diff -ruwN timestamps from all ---/+++ headers
(AGENTS.md patch format policy).
- dropped the three xwayland-glamor.h / xwayland-window.h/c
DRM-only hunks: they commented out xf86drm.h + drmDevice
fields, but the recipe's mesonflags already sets
'-Ddrm=false -Dglamor=false' so those code paths never
compile. Removing them eliminates dead commented-out code
that future maintainers would misread as 'in-progress'.
- replaced hardcoded 0x110/0x112/0x111 button constants
with the symbolic BTN_LEFT/BTN_MIDDLE/BTN_RIGHT names
(the include is now real), matching upstream style and
making the intent self-documenting.
5. local/recipes/libs/mesa/source/src/gallium/winsys/redox/drm/
redox_drm_surface.h: rewrote the stale header comment that
still claimed 'the actual present path is a no-op until
kernel-side scanout ioctls are added' — REDOX_SCANOUT_FLIP
is wired and working; the comment now describes the real
implementation.
6. local/docs/3D-DESKTOP-COMPREHENSIVE-PLAN.md: marked
redbear-wifi-experimental.toml and redbear-bluetooth-
experimental.toml as FIXED 2026-07-27 in the config
status table (the redbear-minimal → redbear-mini typo
was corrected earlier).
7. local/docs/NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md:
struck through Findings 14, 18, 18b, C-21, C-22 and the
corresponding 'Config cleanup' todo — all resolved by
the rename to redbear-mini.toml.
9 files changed, +45/-115.
Two production-code lie-grade fixes from the Round 9 systematic audit
(local/docs/NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md and
local/docs/3D-DESKTOP-COMPREHENSIVE-PLAN.md §10):
1. Mesa redox winsys: redox_drm_fence.{h,c} had a header/implementation
type mismatch. The .h declared
struct pipe_fence_handle *redox_drm_fence_create(...)
but the .c returned uint64_t and passed the scheme fd through pointer
casts ((int)(intptr_t)fence). The pipe_fence_handle struct defined in
the .h was dead code. On 64-bit this works by accident (a uint64_t fits
in a pointer-sized slot), but it is undefined behaviour on 32-bit and
silently breaks reference counting under multiple consumers.
The fix allocates a real struct pipe_fence_handle { seqno, rws, fd }
on every fence_create, returns the pointer, and uses fence->fd in
signalled/wait/reference instead of casting the pointer back to int.
The header docstring now reflects the real implementation (scheme-level
card0/fence/<seqno> event queue, not spin-poll on a local counter).
2. redbear-dnsd: scheme.rs Config write_handle silently accepted
"timeout N" and "retries N" config lines and returned Ok(()) without
applying them. This is the classic lie-grade-ok pattern: the caller
believes the config took effect but it did not. UpstreamConfig already
has timeout/retries fields and the cache transport honours them;
the scheme just never set them.
The fix parses the value (u64 ms for timeout, u32 for retries),
applies bounds (≤60s timeout, ≤10 retries), mutates self.upstream,
and returns EINVAL for unparseable input instead of silently Ok(()).
Duration is now imported alongside Instant.
3 files changed, +43/-29.
The 2026-07-27 Round 9 cleanup deleted 36 docs (3D-DRIVER-PLAN,
WAYLAND-IMPLEMENTATION-PLAN, DRM-MODERNIZATION-EXECUTION-PLAN,
REDBEAR-FULL-SDDM-BRINGUP, and the entire archived/ and
legacy-obsolete-2026-07-25/ contents) but several active docs still
cross-referenced those deleted files. This commit sweeps the surviving
docs and:
* Replaces every deleted-path reference with the live target:
WAYLAND-IMPLEMENTATION-PLAN.md -> 3D-DESKTOP-COMPREHENSIVE-PLAN.md
3D-DRIVER-PLAN.md -> 3D-DESKTOP-COMPREHENSIVE-PLAN.md
REDBEAR-FULL-SDDM-BRINGUP.md -> 3D-DESKTOP-COMPREHENSIVE-PLAN.md
legacy-obsolete-2026-07-25/DRM... -> 3D-DESKTOP-COMPREHENSIVE-PLAN.md
legacy-obsolete-2026-07-25/IRQ... -> IRQ-AND-LOWLEVEL-...-PLAN.md
archived/UPSTREAM-SYNC-PROCEDURE.md -> removed (sync procedure now in
BUILD-CACHE-PLAN.md +
sync-versions.sh)
archived/RELIBC-IPC-ASSESSMENT-... -> removed (work captured in
KERNEL-IPC-CREDENTIAL-PLAN.md)
archived/DRIVER-MANAGER-MIGRATION-PLAN -> removed (history in DRIVER-MANAGER.md
and git log)
archived/INTEL-HDA-IMPLEMENTATION-PLAN -> removed (track now in 3D-DESKTOP-
COMPREHENSIVE-PLAN.md § SOF/AVS)
* Rewrites pcid-spawner references to driver-manager in PACKAGE-BUILD-QUIRKS,
PATCH-GOVERNANCE, NETWORKING-IMPROVEMENT, LG-GRAM-16Z90TP, and the IRQ plan
status note. The retired pcid-spawner service no longer exists in any
redbear-* config as of the 2026-07-24 cutover.
* Rewrites CONSOLE-TO-KDE-DESKTOP-PLAN.md §9 plan table to point at the
post-Round-9 canonical doc map (3D-DESKTOP-COMPREHENSIVE-PLAN.md as the
single coherent 3D-render plan; IRQ plan at top-level). Drops the
misleading 'archived legacy-obsolete-2026-07-25/' status line and the
'work subsumed by Round 1-5' sentence that was explicitly rejected by
SUPERSEDED-DOC-LOG.
* Updates 3D-DESKTOP-COMPREHENSIVE-PLAN.md §10 to mark the REPLACE, RESTORE,
and DELETE pre-execution audit as completed 2026-07-27. Tables remain as
historical record of what was done, with a pointer to the backup tarballs
and SUPERSEDED.md log.
* Bumps 'Last updated' of CONSOLE-TO-KDE-DESKTOP-PLAN.md to v6.1.
13 files changed, +78/-65.
Two production-code stubs in redbear-iwlwifi silently dropped or faked
data; both are now real implementations:
1. bridge/scheme.rs: Mac read with offset >= 6 used to return a
zero-filled packet silently. Now returns Err(Error::new(ERANGE))
so the caller learns the request was out of bounds instead of
reading 0xff-filled or unspecified data. (ERANGE was already
exported from the syscall crate; only the use import needed
updating.)
2. linux_port.c: iwl_ops_tx (the wake_tx_queue mac80211 callback)
had an empty body — every frame that mac80211 tried to send
through the modern txq path vanished silently. Now it maps the
802.11 access category (txq->ac, 0..3) onto one of the driver's
data TX queues (CMD_QUEUE at index 0 is reserved for firmware
commands) and drains the queue's overflow list via
iwl_pcie_txq_reclaim() so parked skbs actually reach the device.
Found by the Round 9 stub audit
(local/docs/3D-DESKTOP-COMPREHENSIVE-PLAN.md §10).
Submodule local/sources/relibc updated to dff28f00, which implements
two panic-site fixes found by the Round 9 stub audit:
* ld_so/linker.rs: RTLD_NOLOAD|RTLD_NOW no longer panics with
todo!(); returns already-loaded id or DlError::NotFound.
* header/dirent/mod.rs: readdir_r() no longer panics with
unimplemented!(); wraps readdir() per POSIX Issue 8.
See submodule commit message for full rationale.
Round-3 closes three real operational gaps from Round-2 follow-ups:
- N9 — SIGHUP reloads all 4 policy surfaces (not just blacklist)
- N10 — initfs-manifest stage-aware probing (was a single pass)
- N11 — linux-kpi SAFETY comment cleanup (already done in
parallel by commits b295b80882 and a56cf84154; documented)
Updated:
- Last-updated banner
- § 5.10.2 Round-3 (N9–N11) summary section
- § 6.1 test inventory table (164 driver-manager tests, 200+ total)
The doc is now consistent with the current source state.
The first-round assessment (NETWORKING-AND-DRIVERS-SYSTEMATIC-
ASSESSMENT-2026-07-27.md) was never committed to the parent 0.3.1
branch. It captures the docs audit that preceded the code audit
(now at NETWORKING-AND-DRIVERS-CODE-ASSESSMENT-2026-07-27.md).
Both files live in the repo as the docs and code halves of the
audit series.
SUPERSEDED-DOC-LOG.md is the change-log file referenced from
local/docs/legacy-obsolete-2026-07-25/SUPERSEDED.md. Previously
untracked; this commit makes it visible to the doc audit trail.
The two comments in drm_crtc_handle_vblank_is_monotonic_over_many_calls
test describe what the test already self-documents via the assert_eq!
and the loop structure. Removing them is a pure simplification,
no behavior change.
The amdgpu C source uses a redox_log() helper to write log messages.
Previously this was likely a no-op stub. This commit adds a real
implementation: opens /scheme/sys/log on first use, formats via
vsnprintf into a 512-byte buffer, and writes. Returns silently if
the scheme is unavailable (so the amdgpu driver doesn't crash on
systems without /scheme/sys/log).
The file is still named redox_stubs.c which is a code smell per
AGENTS.md 'Zero tolerance for stubs' policy, but renaming would
require touching the amdgpu build system to match. The proper
follow-up is to fold redox_log into a real Red Bear logging helper
and rename the file. Tracked as a follow-up.
The previous round of SAFETY doc additions used the generic comment
'// SAFETY: caller must verify the safety contract for this operation'
which was vague and added no information beyond the unsafe keyword.
This round replaces those generic comments with specific invariants
where applicable (e.g. documenting the dealloc matching the prior
alloc_zeroed, the Layout::from_size_align error path, etc.).
Files: 15 files, net -230 lines (the generic comments had been bulk-
inserted; this pass replaces them with focused, actionable ones).
The initfs manifest's [kms]/[block]/[filesystems]/[boot] sections
are no longer just logged — they now drive the initfs boot order.
Previously the initfs manager ran the same single-pass enumeration
as the rootfs manager, ignoring the manifest's stage order. This
was a real gap: KMS drivers that the manifest said should bind
before block drivers could race with the block driver's probe.
New run_initfs_manifest_enumeration function walks the manifest
stages in canonical order, running a full enumerate() pass for
each stage and accumulating bound/deferred counts. A final
fallback pass handles any drivers not listed in the manifest.
In initfs mode + non-empty manifest: stage-aware probing.
In rootfs mode (or empty manifest): the original single-pass path
runs unchanged.
Two dispatch sites (async + sync enumeration) call the new
function conditionally on use_manifest = initfs && !manifest.is_empty().
Each branch logs the stage-driven totals separately so operators
can verify the manifest is wired.
164 driver-manager tests pass (no new tests added: the new code
path is observable only via the actual probe order in QEMU, which
is not exercised by the host test suite). The existing policy
tests still cover the manifest parsing, SIGHUP reload, and stage
enumeration helpers.
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
libredox O_CLOEXEC now references syscall::flag::O_CLOEXEC instead
of duplicating the literal 0x0100_0000. Per Single Source of Truth
and the Local Fork Supremacy Policy: a primitive constant should be
defined once in the most-primitive crate that has it (syscall) and
re-exported by higher-level crates (libredox).
R002 fix: netstack/src/filter/conntrack.rs captured '(is_orig, entry_key)'
in an if/else, but the 'if let' arm early-returned, so is_orig was
always true. Reply-direction state machine was unreachable for
already-established flows. Flattened the conditional: reply-side
'if let' early-returns; fall-through uses original key directly.
The is_orig variable is gone; orig-side path calls
advance_entry_state with is_orig=true explicitly.
The SIGHUP worker previously only reloaded the SharedBlacklist.
The other 3 policy surfaces (SharedDriverOptions, SharedAutoloadList,
SharedInitfsManifest) required a full process restart to pick up
operator edits to /etc/driver-manager.d/*.toml. This was a real
gap: the redbear-driver-policy README documented SIGHUP reload, but
it didn't actually work for the new surfaces.
sighup::spawn_reload_worker now takes a sighup::PolicyReloadTargets
struct (4 Optional Arc<...> fields, one per surface). main.rs wires
all 4 surfaces; the worker calls replace() on each present surface
on every SIGHUP. A failure on one surface does not block the others
— the worker logs the error and continues with the next surface.
The 3 new live Arc<...> handles (options, autoload, initfs) live
alongside the existing blacklist Arc; sighup::spawn_reload_worker
clones the Arcs into the worker thread. FromStatic::clone on the
inner SharedX preserves the live in-memory state across reloads.
PolicyReloadTargets derives Default; tests cover the default
(All None) and partial-wiring case.
Tests (2 new):
- policy_reload_targets_default_is_empty
- policy_reload_targets_supports_partial_wiring
driver-manager tests: 162 -> 164.
driver-manager-audit-no-stubs.py: 46 files, 0 violations.
Three-touchpoint fix for the option level collision (option 4 reads
as TCP_KEEPIDLE at SOL_SOCKET vs IP_TOS at IPPROTO_IP):
1. relibc/src/platform/redox/socket.rs: setsockopt/getsockopt
wire format changed from [SocketCall, option] to
[SocketCall, level, option]. The stale 'TODO convert back to
match when we support more levels' comment removed.
2. base/netstack/src/scheme/socket.rs: SocketT::set_sock_opt and
get_sock_opt now take (level, name) separately. The scheme dispatch
reads metadata[1] as level and metadata[2] as option.
3. base/netstack/src/scheme/{tcp,udp}.rs: TCP and UDP SocketT impls
updated to the new (level, name) signature.