mirror of
https://github.com/lahfir/agent-desktop.git
synced 2026-08-16 12:03:46 +00:00
fix(session): degrade any unreadable manifest, not just symlinks
read_manifest already treated symlinked and corrupt-JSON manifests as a skipped (None) entry, but a plain PermissionDenied on one session's session.json propagated and aborted list_sessions — and therefore gc — for every other session. Degrade all non-NotFound open/read errors the same way so one restricted directory can no longer break enumeration or garbage collection.
This commit is contained in:
parent
53d6800aca
commit
ca50261348
2 changed files with 33 additions and 3 deletions
|
|
@ -107,11 +107,12 @@ pub fn read_manifest(session_id: &str) -> Result<Option<SessionManifest>, AppErr
|
|||
let mut file = match open_session_file(&path) {
|
||||
Ok(file) => file,
|
||||
Err(err) if err.kind() == ErrorKind::NotFound => return Ok(None),
|
||||
Err(err) if is_symlinked(&path) => return Ok(ignore_unreadable_manifest(&path, &err)),
|
||||
Err(err) => return Err(err.into()),
|
||||
Err(err) => return Ok(ignore_unreadable_manifest(&path, &err)),
|
||||
};
|
||||
let mut json = String::new();
|
||||
file.read_to_string(&mut json)?;
|
||||
if let Err(err) = file.read_to_string(&mut json) {
|
||||
return Ok(ignore_unreadable_manifest(&path, &err));
|
||||
}
|
||||
match serde_json::from_str(&json) {
|
||||
Ok(manifest) => Ok(Some(manifest)),
|
||||
Err(err) => Ok(ignore_unreadable_manifest(&path, &err)),
|
||||
|
|
|
|||
|
|
@ -226,6 +226,35 @@ fn corrupt_manifest_is_ignored_not_fatal() {
|
|||
assert!(!listed.iter().any(|id| id == "corruptsess"));
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn unreadable_manifest_is_skipped_not_fatal_for_list_and_gc() {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
if unsafe { libc::geteuid() } == 0 {
|
||||
return;
|
||||
}
|
||||
let _guard = HomeGuard::new();
|
||||
let good = start_session(StartSessionOptions {
|
||||
name: None,
|
||||
trace: SessionTraceMode::Off,
|
||||
force: true,
|
||||
})
|
||||
.unwrap();
|
||||
let bad_dir = session_dir("unreadablesess").unwrap();
|
||||
fs::create_dir_all(&bad_dir).unwrap();
|
||||
let manifest = bad_dir.join("session.json");
|
||||
fs::write(&manifest, b"{}").unwrap();
|
||||
fs::set_permissions(&manifest, fs::Permissions::from_mode(0o000)).unwrap();
|
||||
|
||||
let listed: Vec<String> = list_sessions().unwrap().into_iter().map(|m| m.id).collect();
|
||||
assert!(listed.contains(&good.id));
|
||||
assert!(!listed.iter().any(|id| id == "unreadablesess"));
|
||||
assert!(read_manifest("unreadablesess").unwrap().is_none());
|
||||
|
||||
fs::set_permissions(&manifest, fs::Permissions::from_mode(0o600)).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gc_leaves_recently_created_unended_session() {
|
||||
let _guard = HomeGuard::new();
|
||||
|
|
|
|||
Loading…
Reference in a new issue