{"record":{"id":"ebb93833c514e4f1","repo":"clash-verge-rev/clash-verge-rev","slug":"effective-user-home-lookup-exceeded-the-maximum-bu","errorCode":null,"errorMessage":"effective-user home lookup exceeded the maximum buffer size","messagePattern":"effective-user home lookup exceeded the maximum buffer size","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src-tauri/src/utils/macos_launch_guard.rs","lineNumber":114,"sourceCode":"    std::fs::canonicalize(path).ok()\n}\n\nfn current_user_home() -> anyhow::Result<PathBuf> {\n    const DEFAULT_BUFFER_SIZE: usize = 16 * 1024;\n    const MAX_BUFFER_SIZE: usize = 1024 * 1024;\n\n    let uid = unsafe { libc::geteuid() };\n    let configured_size = unsafe { libc::sysconf(libc::_SC_GETPW_R_SIZE_MAX) };\n    let mut buffer_size = if configured_size > 0 {\n        usize::try_from(configured_size).unwrap_or(DEFAULT_BUFFER_SIZE)\n    } else {\n        DEFAULT_BUFFER_SIZE\n    }\n    .max(1024);\n\n    loop {\n        if buffer_size > MAX_BUFFER_SIZE {\n            anyhow::bail!(\"effective-user home lookup exceeded the maximum buffer size\");\n        }\n\n        let mut passwd = std::mem::MaybeUninit::<libc::passwd>::zeroed();\n        let mut result = std::ptr::null_mut();\n        let mut buffer = vec![0_u8; buffer_size];\n        let code = unsafe {\n            libc::getpwuid_r(\n                uid,\n                passwd.as_mut_ptr(),\n                buffer.as_mut_ptr().cast(),\n                buffer.len(),\n                &mut result,\n            )\n        };\n        if code == libc::ERANGE {\n            buffer_size = buffer_size.saturating_mul(2);\n            continue;\n        }","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/clash-verge-rev/clash-verge-rev/blob/5cad0f2799e74b1105e133bcfc2a45f5c1370ef1/src-tauri/src/utils/macos_launch_guard.rs#L96-L132","documentation":"current_user_home() calls getpwuid_r in a loop, doubling the buffer on each ERANGE return until it exceeds 1 MiB (MAX_BUFFER_SIZE). Bailing past that ceiling stops an unbounded loop: an effective UID whose passwd lookup refuses to fit in a megabyte is treated as broken rather than allowed to grow forever.","triggerScenarios":"A misconfigured Directory Service (Open Directory, the AD plugin, or LDAP) returning getpwuid_r=ERANGE indefinitely; libc on a stripped-down macOS sandbox where sysconf(_SC_GETPW_R_SIZE_MAX) reports a wrong size; a corrupted passwd entry with pathological content.","commonSituations":"macOS bound to a broken AD; containerized/hardened macOS where directory services are restricted; a custom MDM profile that interferes with Open Directory; CI running the launch guard under a synthetic UID.","solutions":["Run `dscacheutil -q user -a uid <uid>` and `id -p` to inspect what Directory Services returns for the user.","Flush the directory cache: `dscacheutil -flushcache` then `killall -HUP mDNSResponder`.","If the Mac is AD-bound, unbind/rebind or fix LDAP reachability to the domain controller.","As a workaround, set the HOME environment variable and (if patched) the code falls back to it before giving up."],"exampleFix":"// before\nif buffer_size > MAX_BUFFER_SIZE {\n    anyhow::bail!(\"effective-user home lookup exceeded the maximum buffer size\");\n}\n// after - fall back to $HOME before giving up\nif buffer_size > MAX_BUFFER_SIZE {\n    if let Some(home) = std::env::var_os(\"HOME\") {\n        return Ok(PathBuf::from(home));\n    }\n    anyhow::bail!(\"effective-user home lookup exceeded the maximum buffer size\");\n}","handlingStrategy":"fallback","validationCode":"fn safe_home() -> anyhow::Result<PathBuf> {\n    match current_user_home() {\n        Ok(p) => Ok(p),\n        Err(_) => std::env::var_os(\"HOME\").map(PathBuf::from)\n            .ok_or_else(|| anyhow::anyhow!(\"no home directory resolvable\")),\n    }\n}","typeGuard":null,"tryCatchPattern":"let home = match current_user_home() {\n    Ok(h) => h,\n    Err(e) => match std::env::var_os(\"HOME\") {\n        Some(h) if !h.is_empty() => PathBuf::from(h),\n        _ => return Err(e),\n    },\n};","preventionTips":["Keep macOS Directory Service healthy; flush caches when lookups misbehave.","For embedded/kiosk/CI contexts, set HOME explicitly so the launch guard can fall back.","Bound the getpwuid_r retry loop (the code already caps at 1 MiB) and always provide an env fallback."],"tags":["macos","libc","directory-service","filesystem"],"analyzedSha":"5cad0f2799e74b1105e133bcfc2a45f5c1370ef1","analyzedAt":"2026-08-12T03:25:57.699Z","schemaVersion":2},"datasetVersion":"2026-08-12T08:17:17.861Z"}