fix: audit fixes — double-unlock guard, PAM OOM code, GPU blur, async fp stop (v0.5.1)

Security: prevent double unlock() when PAM and fingerprint succeed
simultaneously (ext-session-lock protocol error). Fix PAM callback
returning PAM_AUTH_ERR instead of PAM_BUF_ERR on calloc OOM.

Performance: replace CPU-side Gaussian blur (image crate) with GPU blur
via GskBlurNode + GskRenderer::render_texture(). Eliminates 500ms-2s
main-thread blocking on cold cache for 4K wallpapers. Remove image and
dirs dependencies (~15 transitive crates). Make fingerprint stop()
fire-and-forget async to avoid 6s UI block after successful auth.
This commit is contained in:
2026-03-28 22:06:38 +01:00
parent 48706e5a29
commit 4026f6dafa
8 changed files with 87 additions and 447 deletions
+11 -3
View File
@@ -13,7 +13,7 @@ use gdk4 as gdk;
use gtk4::prelude::*;
use gtk4::{self as gtk, gio};
use gtk4_session_lock;
use std::cell::RefCell;
use std::cell::{Cell, RefCell};
use std::rc::Rc;
use crate::fingerprint::FingerprintListener;
@@ -41,7 +41,7 @@ fn activate(app: &gtk::Application) {
let config = config::load_config(None);
let bg_path = config::resolve_background_path(&config);
let bg_texture = lockscreen::load_background_texture(&bg_path, config.background_blur);
let bg_texture = lockscreen::load_background_texture(&bg_path);
if gtk4_session_lock::is_supported() {
activate_with_session_lock(app, &display, &bg_texture, &config);
@@ -70,10 +70,18 @@ fn activate_with_session_lock(
let monitors = display.monitors();
// Shared unlock callback — unlocks session and quits
// Shared unlock callback — unlocks session and quits.
// Guard prevents double-unlock if PAM and fingerprint succeed simultaneously.
let lock_clone = lock.clone();
let app_clone = app.clone();
let already_unlocked = Rc::new(Cell::new(false));
let au = already_unlocked.clone();
let unlock_callback: Rc<dyn Fn()> = Rc::new(move || {
if au.get() {
log::debug!("Unlock already triggered, ignoring duplicate");
return;
}
au.set(true);
lock_clone.unlock();
app_clone.quit();
});