it-swarm-fr.com

Obtention du message "Introuvable" lors de l'exécution d'un binaire 32 bits sur un système 64 bits

J'ai actuellement un étrange problème sur Debian (Wheezy/AMD64).

J'ai créé un chroot pour installer un serveur (je ne peux pas donner plus de détails à ce sujet, désolé). Appelons son chemin /chr_path/. Pour faciliter les choses, j'ai initialisé ce chroot avec un debootstrap (également wheezy/AMD64).

Tout semblait bien fonctionner à l'intérieur du chroot mais quand j'ai commencé le script d'installation de mon serveur, j'ai eu: zsh: Not found /some_path/Perl (le programme d'installation inclut un binaire Perl pour certaines raisons)

Naturellement, j'ai vérifié le /some_path/ emplacement et j'ai trouvé le binaire "Perl". file dans un environnement chroot renvoie:

/some_path/Perl ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.2.5, not stripped

Le fichier existe, semble correct, a les droits corrects. Je peux utiliser file, ls, vim dessus mais dès que j'essaye de l'exécuter - ./Perl par exemple - j'obtiens: zsh: Not found ./Perl.

Cette situation est tout à fait compréhensible pour moi. De plus :

  • Je peux exécuter d'autres binaires de base (/ bin/ls, ...) dans le chroot sans obtenir d'erreurs
  • J'ai les mêmes problèmes pour les autres binaires fournis avec le projet
  • Lorsque j'essaie d'exécuter le binaire à partir de la racine principale (/chr_path/some_path/Perl), Ça marche.
  • J'ai essayé de mettre un des binaires avec une copie de mon ls. J'ai vérifié que les droits d'accès étaient les mêmes mais cela n'a rien changé (l'un fonctionnait et l'autre ne fonctionnait pas)
72
Elenaher

Lorsque vous ne parvenez pas à exécuter un fichier qui dépend d'un "chargeur", l'erreur que vous obtenez peut se référer au chargeur plutôt qu'au fichier que vous exécutez.

  • Le chargeur d'un exécutable natif lié dynamiquement est la partie du système qui est responsable du chargement des bibliothèques dynamiques. C'est quelque chose comme /lib/ld.so ou /lib/ld-linux.so.2, et doit être un fichier exécutable.
  • Le chargeur d'un script est le programme mentionné sur la ligne Shebang, par ex. /bin/sh pour un script commençant par #!/bin/sh. (Bash et zsh donnent un message "mauvais interprète" au lieu de "commande introuvable" dans ce cas.)

Le message d'erreur est plutôt trompeur en n'indiquant pas que le chargeur est le problème. Malheureusement, il serait difficile de résoudre ce problème car l'interface du noyau n'a de place que pour signaler un code d'erreur numérique, pas pour indiquer également que l'erreur concerne en fait un fichier différent. Certains shells font le travail eux-mêmes pour les scripts (lire le #! ligne sur le script et retravailler la condition d'erreur), mais aucune que j'ai vue n'essaye de faire de même pour les binaires natifs.

ldd ne fonctionnera pas non plus sur les binaires car il fonctionne en définissant des variables d'environnement spéciales puis en exécutant le programme, laissant le chargeur faire le travail. strace ne fournirait aucune information significative non plus, car il ne rapporterait pas plus que ce que le noyau rapporte, et comme nous l'avons vu, le noyau ne peut pas rapporter tout ce qu'il sait.

Cette situation se produit souvent lorsque vous essayez d'exécuter un binaire pour le bon système (ou famille de systèmes) et la superarchitecture mais la mauvaise sous-architecture. Ici, vous avez des binaires ELF sur un système qui attend des binaires ELF, donc le noyau les charge très bien. Ce sont des binaires i386 fonctionnant sur un processeur x86_64, donc les instructions ont du sens et amènent le programme au point où il peut rechercher son chargeur. Mais le programme est un programme 32 bits (comme l'indique la sortie file), à la recherche du chargeur 32 bits /lib/ld-linux.so.2, et vous n'avez probablement installé que le chargeur 64 bits /lib64/ld-linux-x86-64.so.2 dans le chroot.

Vous devez installer le système d'exécution 32 bits dans le chroot: le chargeur et toutes les bibliothèques dont les programmes ont besoin. À partir de Debian Wheezy, si vous voulez à la fois la prise en charge i386 et x86_64, commencez par une installation AMD64 et activez la prise en charge multiarch : exécutez dpkg --add-architecture i386 puis apt-get update et apt-get install libc6:i386 zlib1g:i386 … (si vous voulez générer une liste des dépendances du paquet Perl de Debian, pour voir quelles bibliothèques sont susceptibles d'être nécessaires, vous pouvez utiliser aptitude search -F %p '~Rdepends:^Perl$ ~ri386'). Vous pouvez extraire une collection de bibliothèques communes en installant ia32-libs package (vous devez d'abord activer la prise en charge multiarchitecture). Sur Debian AMD64 jusqu'à Wheezy, le chargeur 32 bits est dans le libc6-i386 package. Vous pouvez installer un plus grand ensemble de bibliothèques 32 bits en installant ia32-libs .

Exécutez ldd(1) sur votre binaire Perl. Souvent, la confusion apparente Not found erreur sur un fichier qui est clairement là parce qu'une des bibliothèques partagées utilisées par le programme est introuvable.

Il est donc possible que votre chroot soit incomplet par rapport aux bibliothèques partagées nécessaires à vos binaires.

5
camh