fix: audit fixes — password zeroize, blur downscale, symlink hardening, error filtering (v0.7.0)
Update PKGBUILD version / update-pkgver (push) Successful in 2s
Update PKGBUILD version / update-pkgver (push) Successful in 2s
- Add zeroize dependency, wrap password in Zeroizing<String> from entry extraction through to login_worker (prevents heap-resident plaintext) - Add MAX_BLUR_DIMENSION (1920px) downscale before GPU blur to reduce 4K workload - Wallpaper: use symlink_metadata + is_symlink rejection in greeter.rs and config.rs - Avatar: add is_file() check, swap lookup order to ~/.face first (consistent with moonlock/moonset) - greetd errors: show generic fallback in UI, log raw PAM details at debug level only - fprintd: validate device path prefix before creating D-Bus proxy - Locale: cache detected locale via OnceLock (avoid repeated env/file reads)
This commit is contained in:
+16
-16
@@ -94,7 +94,7 @@ pub fn get_users(passwd_path: Option<&Path>) -> Vec<User> {
|
||||
users
|
||||
}
|
||||
|
||||
/// Find avatar for a user: AccountsService icon > ~/.face > None.
|
||||
/// Find avatar for a user: ~/.face > AccountsService icon > None.
|
||||
/// Rejects symlinks to prevent path traversal.
|
||||
pub fn get_avatar_path(username: &str, home: &Path) -> Option<PathBuf> {
|
||||
get_avatar_path_with(username, home, Path::new(DEFAULT_ACCOUNTSSERVICE_DIR))
|
||||
@@ -106,30 +106,30 @@ pub fn get_avatar_path_with(
|
||||
home: &Path,
|
||||
accountsservice_dir: &Path,
|
||||
) -> Option<PathBuf> {
|
||||
// AccountsService icon takes priority
|
||||
// ~/.face takes priority (consistent with moonlock/moonset)
|
||||
let face = home.join(".face");
|
||||
if let Ok(meta) = face.symlink_metadata() {
|
||||
if meta.file_type().is_symlink() {
|
||||
log::warn!("Rejecting symlink avatar for {username}: {}", face.display());
|
||||
} else if meta.is_file() {
|
||||
log::debug!("Avatar for {username}: ~/.face {}", face.display());
|
||||
return Some(face);
|
||||
}
|
||||
}
|
||||
|
||||
// AccountsService icon fallback
|
||||
if accountsservice_dir.exists() {
|
||||
let icon = accountsservice_dir.join(username);
|
||||
if let Ok(meta) = icon.symlink_metadata() {
|
||||
if meta.file_type().is_symlink() {
|
||||
log::warn!("Rejecting symlink avatar for {username}: {}", icon.display());
|
||||
} else {
|
||||
} else if meta.is_file() {
|
||||
log::debug!("Avatar for {username}: AccountsService {}", icon.display());
|
||||
return Some(icon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ~/.face fallback
|
||||
let face = home.join(".face");
|
||||
if let Ok(meta) = face.symlink_metadata() {
|
||||
if meta.file_type().is_symlink() {
|
||||
log::warn!("Rejecting symlink avatar for {username}: {}", face.display());
|
||||
} else {
|
||||
log::debug!("Avatar for {username}: ~/.face {}", face.display());
|
||||
return Some(face);
|
||||
}
|
||||
}
|
||||
|
||||
log::debug!("No avatar found for {username}");
|
||||
None
|
||||
}
|
||||
@@ -248,7 +248,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn accountsservice_icon_takes_priority() {
|
||||
fn face_file_takes_priority_over_accountsservice() {
|
||||
let dir = tempfile::tempdir().unwrap();
|
||||
let icons_dir = dir.path().join("icons");
|
||||
fs::create_dir(&icons_dir).unwrap();
|
||||
@@ -261,7 +261,7 @@ mod tests {
|
||||
fs::write(&face, "fake face").unwrap();
|
||||
|
||||
let path = get_avatar_path_with("testuser", &home, &icons_dir);
|
||||
assert_eq!(path, Some(icon));
|
||||
assert_eq!(path, Some(face));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user