fix(vfs): V-03 — raii memory lock guard prevents premature memory unlock on fs clone
This commit is contained in:
@@ -154,3 +154,68 @@ fn test_mount_security_multi_auth_and_no_token_in_url() {
|
||||
"Saubere URI darf kein Token enthalten"
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_vfs_memory_lock_retention_on_clone_v03() {
|
||||
use dav_server::davpath::DavPath;
|
||||
use dav_server::fs::{DavFileSystem, ReadDirMeta};
|
||||
use futures_util::StreamExt;
|
||||
use sanctum::vfs::SanctumFs;
|
||||
|
||||
let temp_dir = std::env::temp_dir();
|
||||
let container_path: PathBuf =
|
||||
temp_dir.join(format!("test_v03_lock_{}.sanctum", std::process::id()));
|
||||
if container_path.exists() {
|
||||
let _ = std::fs::remove_file(&container_path);
|
||||
}
|
||||
|
||||
let salt = generate_salt();
|
||||
let kdf_params = KdfParams {
|
||||
memory_cost: MIN_MEMORY_COST_KIB,
|
||||
time_cost: MIN_TIME_COST,
|
||||
parallelism: 1,
|
||||
};
|
||||
let kek = derive_kek("TestPassV03!", &salt, &kdf_params).unwrap();
|
||||
let dek = generate_dek();
|
||||
let (wrapped_dek, nonce, tag) = wrap_dek(&kek, &dek).unwrap();
|
||||
|
||||
let db = Database::open(&container_path).unwrap();
|
||||
db.init_schema(&salt, &kdf_params, &wrapped_dek, &nonce, &tag)
|
||||
.unwrap();
|
||||
|
||||
// 1. Initialisiere SanctumFs
|
||||
let fs = SanctumFs::new(db.clone(), dek, sanctum::crypto::FORMAT_VERSION);
|
||||
assert_eq!(
|
||||
fs.dek_strong_count(),
|
||||
1,
|
||||
"Anfangs muss genau 1 Referenz auf den verriegelten DEK existieren"
|
||||
);
|
||||
|
||||
// 2. Klone SanctumFs (wie bei jeder HTTP/WebDAV-Anfrage im Server)
|
||||
let fs_clone = fs.clone();
|
||||
assert_eq!(
|
||||
fs.dek_strong_count(),
|
||||
2,
|
||||
"Nach dem Klonen müssen 2 Referenzen existieren"
|
||||
);
|
||||
|
||||
// 3. Droppe den Klon
|
||||
drop(fs_clone);
|
||||
|
||||
// 4. V-03: Der Refcount muss nun wieder 1 sein. Der Speicherbereich darf NICHT
|
||||
// vorzeitig über Drop eines Klons entriegelt worden sein!
|
||||
assert_eq!(
|
||||
fs.dek_strong_count(),
|
||||
1,
|
||||
"Nach Drop des Klons muss genau 1 Referenz erhalten bleiben"
|
||||
);
|
||||
|
||||
// Verifiziere funktionale Nutzbarkeit nach Drop des Klons
|
||||
let root_path = DavPath::new("/").unwrap();
|
||||
let mut entries = fs.read_dir(&root_path, ReadDirMeta::None).await.unwrap();
|
||||
assert!(entries.next().await.is_none());
|
||||
|
||||
drop(fs);
|
||||
let _ = std::fs::remove_file(&container_path);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user