{"record":{"id":"37f136a0702107be","repo":"astrid-runtime/astrid","slug":"winfsp-service-parent-pid-is-invalid","errorCode":null,"errorMessage":"WinFsp service parent PID is invalid","messagePattern":"WinFsp service parent PID is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-winfsp/src/win.rs","lineNumber":241,"sourceCode":"    };\n    let mut stdout = std::io::stdout().lock();\n    serde_json::to_writer(&mut stdout, &ready).context(\"encode WinFsp readiness\")?;\n    stdout\n        .write_all(b\"\\n\")\n        .context(\"terminate WinFsp readiness response\")?;\n    stdout.flush().context(\"flush WinFsp readiness\")?;\n\n    let result = private_service_loop(filesystem, listener, &launch).await;\n    let _ = local_transport::remove_endpoint(&launch.control_path);\n    result\n}\n\nfn validate_service_launch(launch: &StorageProviderServiceLaunchV1) -> Result<()> {\n    if launch.schema != STORAGE_FILESYSTEM_SERVICE_LAUNCH_SCHEMA_V1 {\n        bail!(\"unsupported WinFsp service launch schema {}\", launch.schema);\n    }\n    if launch.parent.pid <= 1 || launch.parent.pid == std::process::id() {\n        bail!(\"WinFsp service parent PID is invalid\");\n    }\n    if launch.parent.token.len() < 16\n        || launch.parent.token.len() > 512\n        || launch.parent.token.chars().any(char::is_control)\n    {\n        bail!(\"WinFsp service parent token is invalid\");\n    }\n    if let Some(identity) = launch.parent.start_identity.as_deref()\n        && (identity.is_empty() || identity.len() > 512 || identity.chars().any(char::is_control))\n    {\n        bail!(\"WinFsp service parent start identity is invalid\");\n    }\n    if launch.parent.start_identity.is_none() {\n        bail!(\"WinFsp service parent start identity is required on Windows\");\n    }\n    let lease = &launch.lease;\n    let now = SystemTime::now()\n        .duration_since(UNIX_EPOCH)","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-winfsp/src/win.rs#L223-L259","documentation":"validate_service_launch rejects the parent PID if it is <= 1 or equals the service's own process ID (std::process::id()). A parent PID of 0/1 cannot be a real launching parent, and self-reference would make the liveness check meaningless. This guards the parent-liveness handshake against corrupted or forged launch data.","triggerScenarios":"The launch document contains parent.pid of 0, 1, or the service's own PID — e.g. the parent serialized an uninitialized/default PID, a test harness hard-coded pid 0, or PID fields were reordered during (de)serialization.","commonSituations":"Default-initialized StorageProviderServiceLaunch structs in tests; hand-written launch JSON with a placeholder PID; a parent process re-exec trick that made the recorded PID invalid.","solutions":["Have the parent serialize std::process::id() (a real, live PID) into launch.parent.pid before spawning the service","Fix test harnesses to inject a plausible PID (e.g. the test process's own parent, not 0/1)","Validate the struct is fully populated before writing the launch document","Confirm field order/naming matches the schema if building the JSON by hand"],"exampleFix":"// before\nlet launch = StorageProviderServiceLaunchV1::default(); // parent.pid = 0\n// after\nlet mut launch = StorageProviderServiceLaunchV1::default();\nlaunch.parent.pid = std::process::id();","handlingStrategy":"validation","validationCode":"if launch.parent.pid <= 1 || launch.parent.pid == std::process::id() {\n    return Err(format!(\"invalid parent PID {}\", launch.parent.pid));\n}","typeGuard":"fn has_plausible_parent_pid(launch: &StorageProviderServiceLaunchV1) -> bool {\n    launch.parent.pid > 1 && launch.parent.pid != std::process::id()\n}","tryCatchPattern":"match service_err {\n    Err(e) if e.to_string().contains(\"parent PID is invalid\") => {\n        eprintln!(\"populate launch.parent.pid from the live parent process\");\n    }\n    other => other?,\n}","preventionTips":["Always set parent.pid = std::process::id() in the launcher","Avoid Default-built launch structs in production paths","Validate the launch document before writing it to stdin"],"tags":["windows","winfsp","process","validation"],"backgroundTag":"value-out-of-range","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}