{"record":{"id":"980f29fbe72e7540","repo":"Hmbown/CodeWhale","slug":"android-authority-identifies-runtime-linker","errorCode":null,"errorMessage":"Android {authority} identifies runtime linker `{}`; refusing to use the linker as an update target","messagePattern":"Android (.+?) identifies runtime linker `(.+?)`; refusing to use the linker as an update target","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/cli/src/update.rs","lineNumber":493,"sourceCode":"    })\n}\n\n#[cfg(any(target_os = \"android\", all(test, unix)))]\nfn validate_android_reported_path(authority: &str, path: &Path) -> Result<()> {\n    if !path.is_absolute() {\n        bail!(\n            \"Android {authority} reported non-absolute loaded-image path `{}`\",\n            path.display()\n        );\n    }\n    if path.to_string_lossy().ends_with(\" (deleted)\") {\n        bail!(\n            \"Android {authority} reported deleted loaded image `{}`\",\n            path.display()\n        );\n    }\n    if is_android_linker_name(path) {\n        bail!(\n            \"Android {authority} identifies runtime linker `{}`; refusing to use the linker as an update target\",\n            path.display()\n        );\n    }\n    Ok(())\n}\n\n#[cfg(any(target_os = \"android\", all(test, unix)))]\nfn validate_android_mapping_identity(\n    mapping: &AndroidImageMapping,\n    candidate: &Path,\n) -> Result<()> {\n    use std::os::unix::fs::MetadataExt;\n\n    let candidate_metadata = std::fs::metadata(candidate).with_context(|| {\n        format!(\n            \"failed to stat Android update target {}\",\n            candidate.display()","sourceCodeStart":475,"sourceCodeEnd":511,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/update.rs#L475-L511","documentation":"Independently of the post-canonicalization linker check, validate_android_reported_path rejects paths that are already identifiable as the Android runtime linker (e.g. /system/bin/linker64, /apex/com.android.runtime/bin/linker) as reported by either authority. This is a belt-and-braces guard so the linker is never chosen as an update target even before resolution.","triggerScenarios":"validate_android_reported_path, called from android_loaded_executable_proof_report, when the dladdr-reported path or the maps row path matches is_android_linker_name().","commonSituations":"Marker address resolving into the linker's mapping (explicit loader invocation, unusual build layout); running a shell script or stub whose dladdr falls into the linker; pathological /proc/self/maps contents under custom ROMs.","solutions":["Execute the updater binary directly rather than through /system/bin/linker64 or another loader.","Rebuild/reinstall the binary so the marker function lives in the updater's own text segment.","Confirm you are running the real updater executable, not a wrapper that delegates to the linker.","Report upstream with the reported path if a normal launch still resolves into the linker."],"exampleFix":"// before\n/system/bin/linker64 ./codewhale update\n// after\n./codewhale update","handlingStrategy":"validation","validationCode":"fn is_android_linker_name(p: &std::path::Path) -> bool {\n    p.file_name().and_then(|n| n.to_str())\n        .map(|n| n == \"linker\" || n.starts_with(\"linker\"))\n        .unwrap_or(false)\n}\nif is_android_linker_name(&reported_path) { /* refuse to treat as update target */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Execute the updater directly, never via /system/bin/linker64.","Verify the marker function lives in the updater's own text.","Guard any destructive swap with a linker-name check first.","Test on stock Android before shipping custom ROM support."],"tags":["android","self-update","linker","safety"],"backgroundTag":"unsupported-operation","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}