From 8285bcdf4472dc32750167a33cd9c2b651366010 Mon Sep 17 00:00:00 2001 From: nevaforget Date: Fri, 24 Apr 2026 14:14:11 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20audit=20LOW=20fixes=20=E2=80=94=20dead?= =?UTF-8?q?=20uid,=20home=5Fdir=20warn,=20clippy=20sweep,=20debug=20value?= =?UTF-8?q?=20(v0.8.5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - users::User: drop the unused `uid` field and its getuid() assignment. The compiler dead_code warning is gone, and the synthetic `u32::MAX` sentinel in the panel fallback is obsolete too. - panel: surface a log::warn! when dirs::home_dir() returns None instead of silently falling back to an empty PathBuf that would make avatars look for .face in the current working directory. - Apply three clippy suggestions: two collapsible if-let + && chains in users::get_avatar_path_with and config::resolve_background_path_with, and a redundant closure in panel::execute_action's spawn_blocking. - main: require MOONSET_DEBUG=1 to escalate log verbosity — mere presence of the var must not dump path info into the journal. --- Cargo.lock | 2 +- Cargo.toml | 2 +- DECISIONS.md | 7 +++++++ src/main.rs | 10 ++++++---- src/panel.rs | 19 ++++++++++++------- src/users.rs | 22 ++++++++++------------ 6 files changed, 37 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b633a0f..e013a51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -616,7 +616,7 @@ dependencies = [ [[package]] name = "moonset" -version = "0.8.4" +version = "0.8.5" dependencies = [ "dirs", "gdk-pixbuf", diff --git a/Cargo.toml b/Cargo.toml index 3c3d84a..b5e868d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "moonset" -version = "0.8.4" +version = "0.8.5" edition = "2024" description = "Wayland session power menu with GTK4 and Layer Shell" license = "MIT" diff --git a/DECISIONS.md b/DECISIONS.md index a03015a..5d36d98 100644 --- a/DECISIONS.md +++ b/DECISIONS.md @@ -2,6 +2,13 @@ Architectural and design decisions for Moonset, in reverse chronological order. +## 2026-04-24 – Audit LOW fixes: dead uid field, home_dir warn, clippy sweep, debug value (v0.8.5) + +- **Who**: ClaudeCode, Dom +- **Why**: Five LOW findings cleared in one pass. (1) `User::uid` was populated from `getuid()` but never read — a compiler `dead_code` warning for a field on the public API. (2) Falling back to a synthetic user when `get_current_user()` returned None used `uid: u32::MAX`, an undocumented sentinel that became moot once uid was removed. (3) `dirs::home_dir().unwrap_or_default()` silently yielded `PathBuf::new()` on failure; avatars would then look for `.face` in the current working directory. (4) `cargo clippy` flagged three suggestions (two collapsible `if`, one redundant closure) that had crept in. (5) `MOONSET_DEBUG` promoted log verbosity on mere presence, leaking path information into the journal. +- **Tradeoffs**: Dropping `uid` from `User` is a minor API break for any internal caller expecting the field — none existed. The synthetic fallback now surfaces `log::warn!` when home resolution fails, which should be rare outside of pathological sandbox environments. +- **How**: (1) Remove `pub uid: u32` from `User` and the `uid: uid.as_raw()` assignment in `get_current_user`. (2) Panel fallback drops the `uid` field entirely. (3) `dirs::home_dir().unwrap_or_else(|| { log::warn!(...); PathBuf::new() })`. (4) `cargo clippy --fix` for the two collapsible ifs, manual collapse of `if-let` + `&&` chain, redundant closure replaced with the function itself. (5) `MOONSET_DEBUG` now requires the literal value `"1"` to escalate to Debug. + ## 2026-04-24 – Audit MEDIUM fixes: timeout guard, POSIX locale, button desensitize, wallpaper allowlist (v0.8.4) - **Who**: ClaudeCode, Dom diff --git a/src/main.rs b/src/main.rs index 14f6d77..d546253 100644 --- a/src/main.rs +++ b/src/main.rs @@ -88,10 +88,12 @@ fn setup_logging() { eprintln!("Failed to create journal logger: {e}"); } } - let level = if std::env::var("MOONSET_DEBUG").is_ok() { - log::LevelFilter::Debug - } else { - log::LevelFilter::Info + // Require MOONSET_DEBUG=1 to raise verbosity so mere presence (empty + // value in a session script) cannot escalate journal noise with path + // information an attacker could use. + let level = match std::env::var("MOONSET_DEBUG").ok().as_deref() { + Some("1") => log::LevelFilter::Debug, + _ => log::LevelFilter::Info, }; log::set_max_level(level); } diff --git a/src/panel.rs b/src/panel.rs index 2cc6571..014a21f 100644 --- a/src/panel.rs +++ b/src/panel.rs @@ -7,7 +7,7 @@ use glib::clone; use gtk4::prelude::*; use gtk4::{self as gtk, gio}; use std::cell::RefCell; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::rc::Rc; use std::time::Duration; @@ -208,11 +208,16 @@ pub fn create_panel_window(texture: Option<&gdk::Texture>, blur_radius: Option { diff --git a/src/users.rs b/src/users.rs index 7f8ecc5..9804fef 100644 --- a/src/users.rs +++ b/src/users.rs @@ -12,7 +12,6 @@ pub struct User { pub username: String, pub display_name: String, pub home: PathBuf, - pub uid: u32, } /// Get the currently logged-in user's info from the system. @@ -37,7 +36,6 @@ pub fn get_current_user() -> Option { username: nix_user.name, display_name, home: nix_user.dir, - uid: uid.as_raw(), }) } @@ -65,16 +63,16 @@ pub fn get_avatar_path_with( } // AccountsService icon fallback - if let Some(name) = username { - if accountsservice_dir.exists() { - let icon = accountsservice_dir.join(name); - if let Ok(meta) = icon.symlink_metadata() { - if meta.file_type().is_symlink() { - log::warn!("Rejecting symlink avatar: {}", icon.display()); - } else if meta.is_file() { - log::debug!("Avatar: using AccountsService icon ({})", icon.display()); - return Some(icon); - } + if let Some(name) = username + && accountsservice_dir.exists() + { + let icon = accountsservice_dir.join(name); + if let Ok(meta) = icon.symlink_metadata() { + if meta.file_type().is_symlink() { + log::warn!("Rejecting symlink avatar: {}", icon.display()); + } else if meta.is_file() { + log::debug!("Avatar: using AccountsService icon ({})", icon.display()); + return Some(icon); } } }