Por que os sistemas Unix / Linux não percorrem diretórios até encontrar a versão necessária de uma biblioteca vinculada?

17

Eu tenho um executável binário chamado "alpha" que requer uma biblioteca vinculada (libz.so.1.2.7) que é colocada em /home/username/myproduct/lib/libz.so.1.2.7

Exporto o mesmo para minha instância de terminal antes de gerar meu executável binário executando o seguinte comando.

export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH

Agora, quando eu surgir outro aplicativo "bravo" que requer a mesma biblioteca, mas de versão diferente, isto é, (libz.so.1.2.8) que está disponível no /lib/x86_64-linux-gnu/libz.so.1.2.8sistema, o sistema lança o seguinte erro.

version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)

Se eu desmarcar a opção LD_LIBRARY_PATH, "bravo" inicia bem. Eu entendo que o comportamento acima é porque LD_LIBRARY_PATHtem precedência sobre os caminhos de diretório definidos /etc/ld.so.confenquanto procura bibliotecas vinculadas e, consequentemente, ocorreu o erro acima. Estou curioso para saber por que os desenvolvedores do UNIX / LINUX não criaram o sistema operacional para procurar bibliotecas vinculadas em outros diretórios de acordo com a hierarquia, se a primeira instância da biblioteca é de versão diferente.

Simplificando, os sistemas UNIX / LINUX percorrem um conjunto de diretórios até encontrar a biblioteca necessária. Mas por que ele não faz o mesmo até encontrar a versão esperada em vez de aceitar a primeira instância da biblioteca, independentemente de sua versão?

daedalus_hamlet
fonte
Não tenho muita certeza, mas acho que por segurança. Pessoalmente, eu preferiria não ter que me preocupar com um link simbólico em qualquer lugar das minhas máquinas
Joe
@ Joe Muitas das bibliotecas possuem links simbólicos apontando para eles. libz.so.1é um link simbólico paralibz.so.1.2.8
Nasir Riley

Respostas:

28

Mas por que ele não faz o mesmo até encontrar a versão esperada em vez de aceitar a primeira instância da biblioteca, independentemente de sua versão?

Faz, tanto quanto está ciente. zlib.so.1.2.7e zlib.so.1.2.8ambos têm um soname de zlib.so.1, para que seus alphae bravobinários dizem que precisam zlib.so.1. O carregador dinâmico carrega a primeira biblioteca correspondente que encontra; não sabe que a versão 1.2.8 fornece símbolos adicionais bravonecessários. (É por isso que as distribuições se esforçam para especificar informações de dependência adicionais, como zlib1g (>= 1.2.8)para bravo.)

Você pode achar que isso deve ser fácil de corrigir, mas não é, principalmente porque os binários e as bibliotecas listam os símbolos de que precisam separadamente das bibliotecas de que precisam, portanto, o carregador não pode verificar se uma determinada biblioteca fornece todos os símbolos que são necessários a partir dele. Os símbolos podem ser fornecidos de várias maneiras e a introdução de um link entre os símbolos e as bibliotecas, desde que eles possam quebrar os binários existentes. Há também a diversão adicional da interposição de símbolos para complicar as coisas (e fazer com que desenvolvedores sensíveis à segurança arrancem os cabelos).

Algumas bibliotecas fornecem informações de versão que acabam sendo armazenadas .gnu.version_r, com um link para a biblioteca fornecedora, o que ajudaria aqui, mas libznão é um deles.

(Dados os sonames, eu esperaria que seu alphabinário funcionasse bem zlib.so.1.2.8.)

Stephen Kitt
fonte
E deve-se notar também que o versionamento da biblioteca no estilo GNU é diferente do versionamento semântico (-ish) com o qual estamos mais acostumados. Como eles têm o mesmo número "atual", 1, o zlib.so.1.2.8 não deve fornecer recursos que o zlib.so.1.2.7 não possua, portanto, não importa (do ponto de vista ABI) qual é encontrado. Que isso importe deve ser considerado uma falha.
John Bollinger
4
@ John não, a única garantia é que as bibliotecas com o mesmo soname sejam compatíveis com versões anteriores; as bibliotecas mais recentes podem adicionar recursos, não podem remover nenhum ou alterar nenhum de uma maneira incompatível com versões anteriores. Ou seja, um binário construído contra o zlib 1.2.7 funcionará com esse ou qualquer outro zlib 1; mas um binário construído contra o zlib 1.2.8 não funcionará necessariamente com um zlib 1. mais antigo (e o versionamento semântico permite isso; mas o manuseio do soname não é o versionamento semântico).
Stephen Kitt
1
Estou falando especificamente sobre convenções GNU, como eu disse, e acho que sobre libtool em particular. Nem todo projeto segue essa convenção, então talvez seja muito forte chamar zlib de falha, mas por outro lado, mesmo uma interpretação de versão semântica dos números de versão da biblioteca envolvidos chegaria à mesma conclusão. A compatibilidade forward (binária) nesses casos não é uma promessa inerente ao soname, mas é uma expectativa razoável nesse caso.
John Bollinger
1
Sim, entendo bem a relação entre os números de CRA e SOVERSION, que remonta ao meu ponto original: a situação descrita pelo OP parece inconsistente com o uso correto do esquema de CRA . Evitar problemas como os PO é um dos principais objetivos desse esquema. Se o zlib adicionar uma nova interface binária (versão de a), seu número C deverá ser aumentado. O fato de que esse impacto também pode levar a um aumento de impacto é secundário.
John Bollinger
2
@ John certo, eu suspeito que estamos em um acordo violento e que eu não entendi o que você estava fazendo. zlibnão usa de libtoolqualquer maneira, exceto em Darwin, onde é ar;-).
Stephen Kitt