Fix: nmap-Timeout beendet auch den von sudo geforkten Enkelprozess

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 -<pgid>` die
gesamte Gruppe (sudo + nmap) beendet statt nur des direkten Kindes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnWfGGqHJGh2AhZ6uhotaD
This commit is contained in:
2026-09-13 19:21:28 +02:00
co-authored by Claude Sonnet 5
parent 8d47f957b6
commit 7a033fa19d
+25 -2
View File
@@ -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);