Pourquoi les systèmes Unix / Linux ne parcourent-ils pas les répertoires jusqu'à ce qu'ils trouvent la version requise d'une bibliothèque liée?

17

J'ai un exécutable binaire nommé "alpha" qui nécessite une bibliothèque liée (libz.so.1.2.7) qui est placée à /home/username/myproduct/lib/libz.so.1.2.7

J'exporte le même vers mon instance de terminal avant de générer mon exécutable binaire en exécutant la commande suivante.

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

Maintenant, quand je lance une autre application "bravo" qui nécessite la même bibliothèque mais de version différente, c'est-à-dire (libz.so.1.2.8) qui est disponible dans /lib/x86_64-linux-gnu/libz.so.1.2.8, le système lance l'erreur suivante.

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

Si je désactive le LD_LIBRARY_PATH, "bravo" démarre bien. Je comprends que le comportement ci-dessus est dû à la LD_LIBRARY_PATHpriorité sur les chemins de répertoire définis dans /etc/ld.so.conflors de la recherche de bibliothèques liées et, par conséquent, l'erreur ci-dessus s'est produite. Je suis simplement curieux de savoir pourquoi les développeurs d'UNIX / LINUX n'ont pas conçu le système d'exploitation pour rechercher des bibliothèques liées dans d'autres répertoires selon la hiérarchie si la première instance de bibliothèque est de version différente.

Autrement dit, les systèmes UNIX / LINUX parcourent un ensemble de répertoires jusqu'à ce qu'ils trouvent la bibliothèque requise. Mais pourquoi ne fait-il pas la même chose jusqu'à ce qu'il trouve la version attendue plutôt que d'accepter la première instance de bibliothèque quelle que soit sa version?

daedalus_hamlet
la source
Je ne suis pas tout à fait sûr, mais je suppose que pour la sécurité. Personnellement, je préférerais ne pas avoir à me soucier d'un lien sym n'importe où sur mes machines
Joe
@Joe De nombreuses bibliothèques elles-mêmes ont des liens symboliques pointant vers elles. libz.so.1est un lien symbolique verslibz.so.1.2.8
Nasir Riley

Réponses:

28

Mais pourquoi ne fait-il pas la même chose jusqu'à ce qu'il trouve la version attendue plutôt que d'accepter la première instance de bibliothèque quelle que soit sa version?

Il le fait, à sa connaissance. zlib.so.1.2.7et les zlib.so.1.2.8deux ont un soname zlib.so.1, donc vos binaires alphaet eux bravodisent qu'ils en ont besoin zlib.so.1. Le chargeur dynamique charge la première bibliothèque correspondante qu'il trouve; il ne sait pas que la version 1.2.8 fournit des symboles supplémentaires dont il a bravobesoin. (C'est pourquoi les distributions s'efforcent de spécifier des informations de dépendance supplémentaires, comme zlib1g (>= 1.2.8)pour bravo.)

Vous pourriez penser que cela devrait être facile à corriger, mais ce n'est pas le cas, notamment parce que les binaires et les bibliothèques répertorient les symboles dont ils ont besoin séparément des bibliothèques dont ils ont besoin, de sorte que le chargeur ne peut pas vérifier qu'une bibliothèque donnée fournit tous les symboles qui en sont nécessaires. Les symboles peuvent être fournis de différentes manières, et l'introduction d'un lien entre les symboles et les bibliothèques qui les fournissent pourrait casser les fichiers binaires existants. Il y a aussi le plaisir supplémentaire de l'interposition de symboles pour compliquer les choses (et faire en sorte que les développeurs sensibles à la sécurité se déchirent les cheveux).

Certaines bibliothèques fournissent des informations de version qui finissent par être stockées dans .gnu.version_r, avec un lien vers la bibliothèque fournissant, ce qui aiderait ici, mais libzn'en fait pas partie.

(Compte tenu des sonames, je m'attends à ce que votre alphabinaire fonctionne correctement zlib.so.1.2.8.)

Stephen Kitt
la source
Et il faut également noter que le versionnage de bibliothèque de style GNU est différent du versioning sémantique (-ish) avec lequel nous sommes le plus habitués. Puisqu'ils ont le même numéro "actuel", 1, zlib.so.1.2.8 ne devrait pas fournir de fonctionnalités que zlib.so.1.2.7 ne fournit pas, donc il ne devrait pas avoir d'importance (du point de vue ABI) lequel est a trouvé. Qu'il importe, cela devrait être considéré comme un défaut.
John Bollinger
4
@John non, la seule garantie est que les bibliothèques avec le même soname sont rétrocompatibles; les bibliothèques plus récentes peuvent ajouter des fonctionnalités, elles ne peuvent pas en supprimer ou en modifier d'une manière incompatible en arrière. C'est-à-dire qu'un binaire construit contre zlib 1.2.7 fonctionnera avec celui-ci ou avec n'importe quel zlib 1 plus récent; mais un binaire construit contre zlib 1.2.8 ne fonctionnera pas nécessairement avec un zlib 1. plus ancien (et le versioning sémantique le permet; mais la gestion de soname n'est pas du versioning sémantique.)
Stephen Kitt
1
Je parle spécifiquement des conventions GNU, comme je l'ai dit, et je pense en particulier à libtool . Tous les projets ne suivent pas cette convention, il est donc peut-être trop fort d'appeler zlib imparfait, mais d'un autre côté, même une interprétation de version sémantique des numéros de version de bibliothèque impliqués aboutirait à la même conclusion. Attaquants compatibilité (binaire) dans de tels cas ne sont pas une promesse inhérente à la soname, mais il est une attente raisonnable dans ce cas.
John Bollinger
1
Oui, je comprends bien la relation entre les numéros de l'ARC et la SOVERSION, qui revient à mon point de départ: la situation décrite par le PO semble être incompatible avec une utilisation correcte du régime de l'ARC . Éviter des problèmes tels que les PO est l'un des principaux objectifs de ce programme. Si zlib ajoute une nouvelle (version d'une) interface binaire, alors son nombre C devrait être augmenté. Le fait qu'une telle bosse puisse également conduire à une bosse de soversion est secondaire.
John Bollinger
2
@John à droite, je soupçonne que nous sommes en accord violent et que j'ai mal compris le point que vous aviez soulevé. zlibn'utilise pas de libtooltoute façon, sauf sur Darwin où c'est ar;-).
Stephen Kitt