Hmbown/CodeWhale · critical
Android loaded-image authorities resolved to runtime linker
Error message
Android loaded-image authorities resolved to runtime linker {}; refusing to use the linker as an update target What it means
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.
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.
Example fix
// before: launching via the loader /system/bin/linker64 $PREFIX/bin/codewhale update // after: execute the binary directly $PREFIX/bin/codewhale update
Defensive patterns
Strategy: validation
Validate before calling
const LINKER_NAMES: [&str; 3] = ["linker", "linker64", "linker64-4"];
fn looks_like_linker(p: &std::path::Path) -> bool {
p.file_name().and_then(|n| n.to_str())
.map(|n| LINKER_NAMES.iter().any(|l| n.starts_with(l)))
.unwrap_or(false)
}
if looks_like_linker(&resolved_path) { return Err(anyhow!("resolved to runtime linker")); } Prevention
- 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.
When it happens
Trigger: android_loaded_executable_proof when is_android_linker_name() matches the canonically-resolved path from both authorities.
Common situations: 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.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Android identifies runtime linker ` `; refusing to use the…
- Android reported deleted loaded image
- Android reported non-absolute loaded-image path
- Android dladdr could not locate the updater's loaded image
- Android dladdr returned an empty loaded-image path
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/ca695078ffb6d0f0.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cli/src/update.rs:456
"failed to canonicalize Android dladdr path {}",
dladdr_path.display()
)
})?;
let resolved_mapping = mapping.path.canonicalize().with_context(|| {
format!(
"failed to canonicalize Android loaded-image mapping {}",
mapping.path.display()
)
})?;
if resolved_dladdr != resolved_mapping {
bail!(
"Android loaded-image authorities disagree: dladdr resolved to {}, but /proc/self/maps resolved to {}",
resolved_dladdr.display(),
resolved_mapping.display()
);
}
if is_android_linker_name(&resolved_mapping) {
bail!(
"Android loaded-image authorities resolved to runtime linker {}; refusing to use the linker as an update target",
resolved_mapping.display()
);
}
if !is_executable_file(&resolved_mapping) {
bail!(
"Android loaded image `{}` is not an executable regular file; refusing to select an update target",
resolved_mapping.display()
);
}
validate_android_mapping_identity(&mapping, &resolved_mapping)?;
Ok(AndroidExecutableProof {
path: resolved_mapping,
device_major: mapping.device_major,
device_minor: mapping.device_minor,
inode: mapping.inode,
proof_kind: AndroidExecutableProofKind::DladdrAndProcMaps,View on GitHub (pinned to 73e0f67d83)