{"record":{"id":"161f1d23e9689efd","repo":"astrid-runtime/astrid","slug":"mountpoint-must-be-owned-by-the-current-os-user","errorCode":null,"errorMessage":"mountpoint must be owned by the current OS user: {}","messagePattern":"mountpoint must be owned by the current OS user: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-storage-provider-fuse/src/mountpoint.rs","lineNumber":43,"sourceCode":"            .join(leaf)\n    });\n    if !requested.is_absolute() {\n        bail!(\"mountpoint must be absolute\");\n    }\n    let existed = requested.symlink_metadata().is_ok();\n    if !existed {\n        std::fs::create_dir_all(&requested)\n            .with_context(|| format!(\"create mountpoint {}\", requested.display()))?;\n    }\n    astrid_core::platform_fs::verify_no_redirects(&requested)\n        .with_context(|| format!(\"reject redirected mountpoint {}\", requested.display()))?;\n    let metadata = std::fs::symlink_metadata(&requested)?;\n    if !metadata.is_dir() {\n        bail!(\"mountpoint is not a directory: {}\", requested.display());\n    }\n    let expected_uid = u32::from(getuid());\n    if metadata.uid() != expected_uid {\n        bail!(\n            \"mountpoint must be owned by the current OS user: {}\",\n            requested.display()\n        );\n    }\n    let mode = metadata.permissions().mode();\n    if !existed {\n        std::fs::set_permissions(&requested, Permissions::from_mode(0o700))?;\n    } else if mode & 0o077 != 0 {\n        bail!(\"mountpoint must be owner-private: {}\", requested.display());\n    }\n    if std::fs::read_dir(&requested)?.next().is_some() {\n        bail!(\"mountpoint is not empty: {}\", requested.display());\n    }\n    let canonical = requested\n        .canonicalize()\n        .with_context(|| format!(\"canonicalize mountpoint {}\", requested.display()))?;\n    if mountinfo_contains(&canonical)? {\n        bail!(\"mountpoint is already mounted: {}\", canonical.display());","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage-provider-fuse/src/mountpoint.rs#L25-L61","documentation":"prepare_mountpoint validates the user-supplied FUSE mountpoint directory before mounting. It refuses to proceed if the existing directory is not owned by the current OS user (uid mismatch between symlink_metadata and getuid). This prevents a FUSE mount over a directory controlled by another user, which could leak or capture I/O across privilege boundaries.","triggerScenarios":"Calling prepare_mountpoint with a path to a pre-existing directory owned by another uid (e.g. root-created directory, another user's home dir, or a directory whose ownership changed after creation).","commonSituations":"Running the service under systemd or a container as a different user than the one that created the mountpoint directory; an admin pre-creating /mnt/myfuse as root; chown'ing the mountpoint by mistake.","solutions":["chown the mountpoint directory to the user running the FUSE service (chown $(id -u) <path>)","Remove the directory so prepare_mountpoint recreates it with correct ownership","Run the service as the user who owns the directory","Verify with stat -c '%u' <path> that the uid matches the running process"],"exampleFix":"// before\nsudo mkdir /mnt/myfuse   # owned by root\n// after\nsudo mkdir /mnt/myfuse && sudo chown $(id -u):$(id -g) /mnt/myfuse","handlingStrategy":"validation","validationCode":"use nix::unistd::getuid;\nfn mountpoint_owned_by_current_user(path: &std::path::Path) -> std::io::Result<bool> {\n    let md = std::fs::symlink_metadata(path)?;\n    Ok(md.is_dir() && md.uid() == u32::from(getuid()))\n}","typeGuard":"fn is_owned_by_current_user(md: &std::fs::Metadata) -> bool {\n    md.is_dir() && md.uid() == u32::from(nix::unistd::getuid())\n}","tryCatchPattern":"match prepare_mountpoint(&path) {\n    Err(e) if e.to_string().contains(\"owned by the current OS user\") => {\n        eprintln!(\"fix ownership: chown {} $(id -u)\", path.display());\n    }\n    Err(e) => return Err(e),\n    Ok(mount) => mount,\n}","preventionTips":["Let prepare_mountpoint create the mountpoint itself instead of pre-creating it","Never chown the mountpoint to root or another user after creation","Check `stat -c '%U' <path>` matches the user running the service before mounting","In systemd units, set User= to the owner of the mountpoint directory"],"tags":["fuse","filesystem","ownership","permissions"],"backgroundTag":"permission-denied","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"}