From 7a033fa19d9d23fcf8c6bd7d02aa7b922f94387e Mon Sep 17 00:00:00 2001 From: DragonSlayer_14 Date: Sun, 13 Sep 2026 19:21:28 +0200 Subject: [PATCH] Fix: nmap-Timeout beendet auch den von sudo geforkten Enkelprozess MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cmd.kill_on_drop(true) signalisiert bei einem Timeout nur den direkten Kind-Prozess. Im Sudo-Fall ist das `sudo` selbst, nicht das davon geforkte, als root laufende `nmap` - dieses lief als root-Waise nach Timeout unbegrenzt weiter, statt vom Timeout begrenzt zu werden. Der nmap/sudo-Prozess läuft jetzt in einer eigenen Prozessgruppe (process_group(0)). Bei einem Timeout wird per `kill -KILL -` die gesamte Gruppe (sudo + nmap) beendet statt nur des direkten Kindes. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01SnWfGGqHJGh2AhZ6uhotaD --- src/network.rs | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/network.rs b/src/network.rs index 920bcbf..da42b20 100644 --- a/src/network.rs +++ b/src/network.rs @@ -95,10 +95,33 @@ pub async fn run_nmap_scan( // unabhängig von der System-Locale funktioniert (z. B. "Passwort ist notwendig" // auf einem deutschen System würde sonst nicht erkannt werden). cmd.env("LC_ALL", "C").env("LANG", "C"); + cmd.kill_on_drop(true); + // Eigene Prozessgruppe: `kill_on_drop`/Child::kill() signalisiert bei einem + // Timeout nur den direkten Kind-Prozess. Im Sudo-Fall ist das `sudo` selbst, + // nicht das von `sudo` geforkte (als root laufende) `nmap`. Ohne eigene + // Prozessgruppe würde `sudo` beim SIGKILL sterben, während `nmap` als + // root-Waise weiterläuft und den Scan fortsetzt. + cmd.process_group(0); - let out = tokio::time::timeout(Duration::from_secs(timeout_secs), cmd.output()) + let child = cmd.spawn()?; + let pgid = child.id(); + + let out = match tokio::time::timeout(Duration::from_secs(timeout_secs), child.wait_with_output()) .await - .map_err(|_| NmapRunError::Timeout)??; + { + Ok(out) => out?, + Err(_) => { + if let Some(pgid) = pgid { + // Negative PID = Signal an die gesamte Prozessgruppe (sudo + nmap). + let _ = tokio::process::Command::new("kill") + .arg("-KILL") + .arg(format!("-{pgid}")) + .output() + .await; + } + return Err(NmapRunError::Timeout); + } + }; if !out.status.success() { let stderr = String::from_utf8_lossy(&out.stderr);