it-swarm.it

Messaggio "Non trovato" durante l'esecuzione di un file binario a 32 bit su un sistema a 64 bit

Attualmente ho uno strano problema su debian (wheezy/AMD64).

Ho creato un chroot per installare un server (non posso fornire ulteriori dettagli a riguardo, scusate). Chiamiamo il suo percorso /chr_path/. Per semplificare le cose, ho inizializzato questo chroot con un debootstrap (anche wheezy/AMD64).

Tutto sembrava funzionare bene all'interno del chroot ma quando ho avviato lo script di installazione del mio server ho ottenuto: zsh: Not found /some_path/Perl (il programma di installazione include un binario Perl per alcuni motivi)

Naturalmente, ho controllato il /some_path/ location e ho trovato il binario "Perl". file nell'ambiente chroot restituisce:

/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

Il file esiste, sembra ok, ha i diritti corretti. Posso usare file, ls, vim ma non appena provo ad eseguirlo - ./Perl ad esempio - Ottengo: zsh: Not found ./Perl.

Questa situazione è abbastanza comprensibile per me. Inoltre :

  • Posso eseguire altri file binari di base (/ bin/ls, ...) nel chroot senza ottenere errori
  • Ho gli stessi problemi per altri file binari forniti con il progetto
  • Quando provo ad eseguire il binario dalla radice principale (/chr_path/some_path/Perl), Funziona.
  • Ho provato a mettere uno dei binari con una copia del mio ls. Ho verificato che i diritti di accesso fossero gli stessi, ma ciò non ha cambiato nulla (uno funzionava e l'altro no)
72
Elenaher

Quando non si riesce a eseguire un file che dipende da un "caricatore", l'errore che si ottiene può riferirsi al caricatore anziché al file che si sta eseguendo.

  • Il caricatore di un eseguibile nativo collegato dinamicamente è la parte del sistema che è responsabile del caricamento delle librerie dinamiche. È qualcosa come /lib/ld.so o /lib/ld-linux.so.2 e dovrebbe essere un file eseguibile.
  • Il caricatore di uno script è il programma menzionato sulla linea Shebang, ad es. /bin/sh per uno script che inizia con #!/bin/sh. (Bash e zsh danno un messaggio "cattivo interprete" invece di "comando non trovato" in questo caso.)

Il messaggio di errore è piuttosto fuorviante nel non indicare che il caricatore è il problema. Sfortunatamente, risolvere questo problema sarebbe difficile perché l'interfaccia del kernel ha spazio solo per segnalare un codice di errore numerico, non per indicare anche che l'errore riguarda effettivamente un file diverso. Alcune shell eseguono il lavoro autonomamente per gli script (leggendo il #! line sullo script e rielaborare la condizione di errore), ma nessuno di quelli che ho visto tenta di fare lo stesso per i binari nativi.

ldd non funzionerà sui binari perché funziona impostando alcune variabili di ambiente speciali e quindi eseguendo il programma, lasciando che il caricatore faccia il lavoro. strace non fornirebbe alcuna informazione significativa, dal momento che non riferirebbe più di quello che riporta il kernel, e come abbiamo visto il kernel non può riportare tutto ciò che sa.

Questa situazione si presenta spesso quando si tenta di eseguire un binario per il sistema giusto (o la famiglia di sistemi) e la superarchitettura ma la sottoarchitettura errata. Qui hai binari ELF su un sistema che prevede binari ELF, quindi il kernel li carica bene. Sono binari i386 in esecuzione su un processore x86_64, quindi le istruzioni hanno senso e portano il programma al punto in cui può cercare il suo caricatore. Ma il programma è un programma a 32 bit (come indica l'output file), cercando il caricatore a 32 bit /lib/ld-linux.so.2 e presumibilmente hai installato solo il caricatore a 64 bit /lib64/ld-linux-x86-64.so.2 nel chroot.

Devi installare il sistema di runtime a 32 bit nel chroot: il caricatore e tutte le librerie di cui i programmi hanno bisogno. Da Debian wheezy in poi, se si desidera sia il supporto i386 che x86_64, iniziare con un'installazione AMD64 e attivare multiarch support: run dpkg --add-architecture i386 poi apt-get update e apt-get install libc6:i386 zlib1g:i386 … (se vuoi generare un elenco delle dipendenze del pacchetto Perl di Debian, per vedere quali librerie potrebbero essere necessarie, puoi usare aptitude search -F %p '~Rdepends:^Perl$ ~ri386'). Puoi inserire una raccolta di librerie comuni installando ia32-libs pacchetto (devi prima abilitare il supporto multiarch). Su Debian AMD64 fino a wheezy, il caricatore a 32 bit è in libc6-i386 pacchetto. Puoi installare un set più grande di librerie a 32 bit installando ia32-libs .

Esegui ldd(1) sul tuo binario Perl. Spesso l'apparentemente confuso Not found errore su un file chiaramente presente perché non è stata trovata una delle librerie condivise utilizzate dal programma.

Quindi è possibile che il chroot sia incompleto rispetto alle librerie condivise necessarie ai tuoi binari.

5
camh