{"record":{"id":"ca695078ffb6d0f0","repo":"Hmbown/CodeWhale","slug":"android-loaded-image-authorities-resolved-to-runti","errorCode":null,"errorMessage":"Android loaded-image authorities resolved to runtime linker {}; refusing to use the linker as an update target","messagePattern":"Android loaded-image authorities resolved to 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":456,"sourceCode":"            \"failed to canonicalize Android dladdr path {}\",\n            dladdr_path.display()\n        )\n    })?;\n    let resolved_mapping = mapping.path.canonicalize().with_context(|| {\n        format!(\n            \"failed to canonicalize Android loaded-image mapping {}\",\n            mapping.path.display()\n        )\n    })?;\n    if resolved_dladdr != resolved_mapping {\n        bail!(\n            \"Android loaded-image authorities disagree: dladdr resolved to {}, but /proc/self/maps resolved to {}\",\n            resolved_dladdr.display(),\n            resolved_mapping.display()\n        );\n    }\n    if is_android_linker_name(&resolved_mapping) {\n        bail!(\n            \"Android loaded-image authorities resolved to runtime linker {}; refusing to use the linker as an update target\",\n            resolved_mapping.display()\n        );\n    }\n    if !is_executable_file(&resolved_mapping) {\n        bail!(\n            \"Android loaded image `{}` is not an executable regular file; refusing to select an update target\",\n            resolved_mapping.display()\n        );\n    }\n\n    validate_android_mapping_identity(&mapping, &resolved_mapping)?;\n    Ok(AndroidExecutableProof {\n        path: resolved_mapping,\n        device_major: mapping.device_major,\n        device_minor: mapping.device_minor,\n        inode: mapping.inode,\n        proof_kind: AndroidExecutableProofKind::DladdrAndProcMaps,","sourceCodeStart":438,"sourceCodeEnd":474,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/cli/src/update.rs#L438-L474","documentation":"Even when dladdr and /proc/self/maps agree, the resolved loaded image could be the runtime linker itself (e.g. /system/bin/linker64) rather than the updater binary — which happens when the marker address maps into the linker's own text. The updater refuses to use the linker as an update target because overwriting the linker would brick dynamic execution on the device.","triggerScenarios":"android_loaded_executable_proof when is_android_linker_name() matches the canonically-resolved path from both authorities.","commonSituations":"Marker function inlined or placed in a section that resolves into the linker's mapping; running the binary via an unusual loader invocation (e.g. `/system/bin/linker64 ./binary`); builds with PIE/linker-script oddities on Android.","solutions":["Run the updater binary normally (exec it directly, not via the linker/loader explicitly).","Rebuild or re-install the binary so its text does not resolve into the linker's mapping; verify with `readelf -l` where the entry point sits.","Ensure the release binary being updated is the actual updater executable, not a stub launched through the linker.","If hit reproducibly on a specific build, report the build/link flags upstream — the marker function placement is pathological."],"exampleFix":"// before: launching via the loader\n/system/bin/linker64 $PREFIX/bin/codewhale update\n// after: execute the binary directly\n$PREFIX/bin/codewhale update","handlingStrategy":"validation","validationCode":"const LINKER_NAMES: [&str; 3] = [\"linker\", \"linker64\", \"linker64-4\"];\nfn looks_like_linker(p: &std::path::Path) -> bool {\n    p.file_name().and_then(|n| n.to_str())\n        .map(|n| LINKER_NAMES.iter().any(|l| n.starts_with(l)))\n        .unwrap_or(false)\n}\nif looks_like_linker(&resolved_path) { return Err(anyhow!(\"resolved to runtime linker\")); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never launch the updater via the dynamic linker explicitly.","Ensure the binary's text segment is its own (check readelf -l).","Ship self-update only for the real updater executable.","Sanity-check the resolved path before any destructive swap."],"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"}