{"record":{"id":"1ecd056afea3ef9d","repo":"astrid-runtime/astrid","slug":"fuse-service-control-path-is-malformed","errorCode":null,"errorMessage":"FUSE service control path is malformed","messagePattern":"FUSE service control path is malformed","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fuse/src/service.rs","lineNumber":277,"sourceCode":"        .context(\"validate private FUSE service mountpoint\")?;\n    platform_fs::verify_no_redirects(mountpoint)\n        .context(\"reject redirected FUSE service mountpoint\")?;\n    if std::fs::read_dir(mountpoint)?.next().is_some() {\n        bail!(\"FUSE service mountpoint is not empty\");\n    }\n    if mountpoint::mountinfo_contains(mountpoint)? {\n        bail!(\"FUSE service mountpoint is already mounted\");\n    }\n    Ok(())\n}\n\nfn validate_control_path(control_path: &Path, resource_path: &Path) -> Result<()> {\n    if !control_path.is_absolute()\n        || control_path\n            .components()\n            .any(|component| matches!(component, std::path::Component::ParentDir))\n    {\n        bail!(\"FUSE service control path is malformed\");\n    }\n    if control_path != resource_path.join(\"process-control.sock\") {\n        bail!(\"FUSE service control path is not the kernel endpoint\");\n    }\n    let parent = control_path\n        .parent()\n        .context(\"FUSE service control path has no parent\")?;\n    platform_fs::validate_private_directory(parent)\n        .context(\"validate private FUSE control parent\")?;\n    platform_fs::verify_no_redirects(control_path)\n        .context(\"reject redirected FUSE control path\")?;\n    if local_transport::endpoint_is_present(control_path)\n        .context(\"inspect FUSE service control endpoint\")?\n    {\n        bail!(\"FUSE service control endpoint is already present\");\n    }\n    Ok(())\n}","sourceCodeStart":259,"sourceCodeEnd":295,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fuse/src/service.rs#L259-L295","documentation":"validate_control_path requires the control path to be absolute and free of ParentDir (\"..\") components before it is compared against the canonical kernel endpoint location. A relative or traversal-containing control path cannot be trusted to resolve to the intended socket location inside the private directory, so the launch is rejected.","triggerScenarios":"Calling validate_launch with a control_path that is relative or contains a \"..\" component.","commonSituations":"Config templates substituting relative paths; building the socket path via string concatenation instead of Path::join; environment expansion introducing \"..\"; copy-pasting a path from a different working directory context.","solutions":["Make control_path absolute (e.g. /run/astrid/leases/<id>/process-control.sock) before launch","Build the path with Path::join from the resource_path rather than string concatenation","Normalize the path to remove any \"..\" components before passing it","Fix the config/env value that introduces relative segments"],"exampleFix":"// before\nlet control_path = \"../leases/demo/process-control.sock\";\n\n// after\nlet control_path = resource_path.join(\"process-control.sock\");","handlingStrategy":"validation","validationCode":"let p = std::path::absolute(control_path)?;\nassert!(p.is_absolute());\nassert!(!p.components().any(|c| matches!(c, std::path::Component::ParentDir)));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive the control path with Path::join from resource_path","Reject relative or \"..\"-containing socket paths in config"],"tags":["fuse","path-validation","control-socket","path-traversal"],"backgroundTag":"invalid-argument-format","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}