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:
+25
-2
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user