Fix: TOCTOU in remove_pair() bei nebenläufigem Schreiber
Die "vorher"-Länge wurde über einen separaten, vorgelagerten load() ermittelt statt innerhalb desselben atomaren modify()-Aufrufs - zwischen beiden Aufrufen konnte ein nebenläufiger Schreiber die Paarliste ändern, was zu einem falschen PairNotFound trotz erfolgreichem Entfernen führen konnte. Der Vorher/Nachher-Vergleich läuft jetzt vollständig innerhalb des modify()-Closures. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LjyzpGWECyKSBWz5DtkTGz
This commit is contained in:
+9
-2
@@ -31,11 +31,18 @@ pub fn update_pair(pair: DrivePair) -> Result<AppConfig> {
|
||||
|
||||
/// Entfernt ein Laufwerkspaar per ID.
|
||||
pub fn remove_pair(id: &str) -> Result<AppConfig> {
|
||||
let before_len = load()?.pairs.len();
|
||||
// Die "vorher"-Länge wird INNERHALB desselben `modify`-Aufrufs (auf der bereits frisch
|
||||
// geladenen `cfg`) ermittelt statt über einen separaten, vorgelagerten `load()`-Aufruf:
|
||||
// zwischen zwei getrennten Aufrufen könnte ein nebenläufiger Schreiber die Paarliste
|
||||
// ändern, was hier sonst zu einem falschen `PairNotFound` trotz erfolgreichem Entfernen
|
||||
// (oder umgekehrt) führen könnte.
|
||||
let removed = std::cell::Cell::new(false);
|
||||
let updated = config_ctdra::modify::<AppConfig, _>(|cfg| {
|
||||
let before_len = cfg.pairs.len();
|
||||
cfg.pairs.retain(|p| p.id != id);
|
||||
removed.set(cfg.pairs.len() != before_len);
|
||||
})?;
|
||||
if updated.pairs.len() == before_len {
|
||||
if !removed.get() {
|
||||
return Err(Error::PairNotFound(id.to_string()));
|
||||
}
|
||||
Ok(updated)
|
||||
|
||||
Reference in New Issue
Block a user