Fix 29 audit findings across all severity tiers

Critical: fix unsquashfs arg order, quote Exec paths with spaces,
fix compare_versions antisymmetry, chunk-based signature detection,
bounded ELF header reads.

High: handle NULL CVE severity, prevent pipe deadlock in inspector,
fix glob_match edge case, fix backup archive path collisions, async
crash detection with stderr capture.

Medium: gate scan on auto-scan setting, fix window size persistence,
fix announce() for Stack containers, claim lightbox gesture, use
serde_json for CLI output, remove dead CSS @media blocks, add
detail-tab persistence, remove invalid metainfo categories, byte-level
fuse signature search.

Low: tighten Wayland env var detection, ELF magic validation,
timeout for update info extraction, quoted arg parsing, stop watcher
timer on window destroy, GSettings choices/range constraints, remove
unused CSS classes, define status-ok/status-attention CSS.
This commit is contained in:
lashman
2026-02-27 22:08:53 +02:00
parent f87403794e
commit e9343da249
27 changed files with 1737 additions and 250 deletions

View File

@@ -38,7 +38,6 @@ pub struct AppImageMetadata {
pub app_version: Option<String>,
pub description: Option<String>,
pub developer: Option<String>,
#[allow(dead_code)]
pub icon_name: Option<String>,
pub categories: Vec<String>,
pub desktop_entry_content: String,
@@ -246,7 +245,7 @@ fn extract_metadata_files(
.arg("usr/share/metainfo/*.xml")
.arg("usr/share/appdata/*.xml")
.stdout(std::process::Stdio::null())
.stderr(std::process::Stdio::piped())
.stderr(std::process::Stdio::null())
.status();
match status {
@@ -430,8 +429,20 @@ fn detect_architecture(path: &Path) -> Option<String> {
let mut header = [0u8; 20];
file.read_exact(&mut header).ok()?;
// ELF e_machine at offset 18 (little-endian)
let machine = u16::from_le_bytes([header[18], header[19]]);
// Validate ELF magic
if &header[0..4] != b"\x7FELF" {
return None;
}
// ELF e_machine at offset 18, endianness from byte 5
let machine = if header[5] == 2 {
// Big-endian
u16::from_be_bytes([header[18], header[19]])
} else {
// Little-endian (default)
u16::from_le_bytes([header[18], header[19]])
};
match machine {
0x03 => Some("i386".to_string()),
0x3E => Some("x86_64".to_string()),
@@ -529,12 +540,42 @@ fn find_appstream_file(extract_dir: &Path) -> Option<PathBuf> {
/// Check if an AppImage has a GPG signature by looking for the .sha256_sig section name.
fn detect_signature(path: &Path) -> bool {
let data = match fs::read(path) {
Ok(d) => d,
use std::io::{BufReader, Read};
let file = match fs::File::open(path) {
Ok(f) => f,
Err(_) => return false,
};
let needle = b".sha256_sig";
data.windows(needle.len()).any(|w| w == needle)
let mut reader = BufReader::new(file);
let mut buf = vec![0u8; 64 * 1024];
let mut carry = Vec::new();
loop {
let n = match reader.read(&mut buf) {
Ok(0) => break,
Ok(n) => n,
Err(_) => break,
};
// Prepend carry bytes from previous chunk to handle needle spanning chunks
let search_buf = if carry.is_empty() {
&buf[..n]
} else {
carry.extend_from_slice(&buf[..n]);
carry.as_slice()
};
if search_buf.windows(needle.len()).any(|w| w == needle) {
return true;
}
// Keep the last (needle.len - 1) bytes as carry for the next iteration
let keep = needle.len() - 1;
carry.clear();
if n >= keep {
carry.extend_from_slice(&buf[n - keep..n]);
} else {
carry.extend_from_slice(&buf[..n]);
}
}
false
}
/// Cache an icon file to the driftwood icons directory.