Isso é amplamente coberto por a prelink
manpage :
prelink
is a program that modifies ELF shared libraries and ELF dynamically linked binaries in such a way that the time needed for the dynamic linker to perform relocations at startup significantly decreases. Due to fewer relocations, the run-time memory consumption decreases as well (especially the number of unshareable pages). The prelinking information is only used at startup time if none of the dependent libraries have changed since prelinking; otherwise programs are relocated normally.
prelink
first collects ELF binaries to be prelinked and all the ELF shared libraries they depend on. Then it assigns a unique virtual address space slot to each library and relinks the shared library to that base address. When the dynamic linker attempts to load such a library, unless that virtual address space slot is already occupied, it maps the library into the given slot. After this is done,prelink
, with the help of dynamic linker, resolves all relocations in the binary or library against its dependent libraries and stores the relocations into the ELF object. It also stores a list of all dependent libraries together with their checksums into the binary or library. For binaries, it also computes a list of conflicts (relocations that resolve differently in the binary's symbol search scope than in the smaller search scope in which the dependent library was resolved) and stores it into a special ELF section.At runtime, the dynamic linker first checks whether all dependent libraries were successfully mapped into their designated address space slots, and whether they have not changed since the prelinking was done. If all checks are successful, the dynamic linker just replays the list of conflicts (which is usually significantly shorter than total number of relocations) instead of relocating each library.
A principal diferença entre ld.so
e prelink
é que o primeiro é executado toda vez que um binário vinculado dinamicamente é carregado. prelink
tenta reduzir o tempo e a memória ocupada por ld.so
na inicialização do programa, pré-calculando as relocações da biblioteca envolvidas na vinculação dinâmica de um binário; ele armazena essas realocações, juntamente com as informações necessárias para determinar se elas ainda são válidas, no binário, e ld.so
pode usar essas informações para ignorar sua própria realocação (contanto que as realocações pré-vinculadas funcionem).
A utilização de prelink
tem várias consequências adversas, em particular:
- modifica os binários, o que significa que eles não podem mais ser comparados à sua "origem" (pacote etc.) para determinar se foram adulterados;
- resulta em realocações fixas, o que reduz enormemente o escopo da randomização de layout do espaço de endereço e reduz a segurança do sistema (para qualquer binário pré-vinculado, desde que as bibliotecas vinculadas não alterem as realocações permanecerão mesmo, o que é muito útil para um invasor tentando explorar um gadget em uma das bibliotecas).