Skip to content

Ask the linker where a library is loaded, not the maps file - #959

Merged
JingMatrix merged 1 commit into
masterfrom
elf-base-from-linker
Sep 7, 2026
Merged

Ask the linker where a library is loaded, not the maps file#959
JingMatrix merged 1 commit into
masterfrom
elf-base-from-linker

Conversation

@JingMatrix

Copy link
Copy Markdown
Owner

ElfImage guessed a library's base from the permission columns of /proc/self/maps, hunting for an r--p line followed by r-xp. The kernel never promised that shape and it does not hold — Android 10 maps libart's text --xp — and our own MAP_SHARED view of the file is itself an offset-0 line that can sort below the real load.

The linker holds the answer already. do_dl_iterate_phdr walks solist in load order and hands over each module's realpath and program headers, so the base falls out of the first PT_LOAD — no parsing, and one less read of maps to be noticed by. Re-entering it from the do_dlopen hook is safe, since g_dl_mutex is recursive.

One gap: the linker's own entry carries no program headers before Android 10, where get_libdl_info begins copying them and soinfo zeroes everything else, so /linker still falls back on 8.1 and 9. That fallback now takes the offset-0 private mapping and corroborates it with an executable one rather than guessing.

Also here: an ELF magic check before parsing, and IsValid() no longer claims an image whose file never opened.

ElfImage guessed a library's base from the permission columns of
/proc/self/maps, hunting for an r--p line followed by r-xp. The kernel
never promised that shape and it does not hold -- Android 10 maps
libart's text --xp -- and our own MAP_SHARED view of the file is itself
an offset-0 line that can sort below the real load.

The linker holds the answer already. do_dl_iterate_phdr walks solist in
load order and hands over each module's realpath and program headers, so
the base falls out of the first PT_LOAD: no parsing, and one less read of
maps to be noticed by. Re-entering it from the do_dlopen hook is safe,
since g_dl_mutex is recursive.

One gap: the linker's own entry carries no program headers before
Android 10, where get_libdl_info begins copying them and soinfo zeroes
everything else, so /linker still falls back on 8.1 and 9. That fallback
now takes the offset-0 private mapping and corroborates it with an
executable one rather than guessing.

Also here: an ELF magic check before parsing, and IsValid() no longer
claims an image whose file never opened.
@JingMatrix
JingMatrix merged commit efb8288 into master Sep 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant