Verwenden von alternate libc mit ld-linux.so-Hacks; sauberere Methode?

13

Ich habe ein Altsystem mit einer sehr alten Glibc, die wir nicht aktualisieren können, ohne einen Berg von Test- / Validierungsarbeiten zu verursachen.

Ich musste jetzt mehrmals neuere Programme (wie Java 1.7) auf diesem System ausführen. Ich habe mich für eine Chroot-Lösung entschieden, bei der ich alle benötigten Bibliotheken gepackt und einen Dienst in einer Chroot ausgeführt habe.

Die Chroot ist jedoch sehr einschränkend, und ich würde lieber versuchen, das Problem mit LD_LIBRARY_PATH zu lösen. Leider erhalte ich eine Fehlermeldung, libc.so.6: cannot handle TLS datawenn ich das versuche.

Es stellt sich heraus, dass ich das auch /lib/ld-linux.so.2von der Chroot brauche . Das funktioniert:

LD_LIBRARY_PATH=/home/chroot/lib /home/chroot/lib/ld-linux.so.2 /home/chroot/bin/program

Dies javavereitelt jedoch meinen Trick, indem untersucht wird /proc/self/cmdline, woher die Bibliotheken geladen werden sollen. Dies schlägt fehl, wenn die Binärdatei nicht den Namen 'bin / java' trägt. Auch Java führt sich beim Start von selbst aus, was die Sache noch komplizierter macht.

In einem letzten Versuch, dies zum Laufen zu bringen, öffnete ich die Java-Binärdatei mit einem Hex-Editor und ersetzte die Zeichenfolge /lib/ld-linux.so.2durch /home/chroot/ld.so(und machte daraus einen Symlink zu ld-linux.so.2), und es funktionierte!

Aber ich denke, jeder würde zustimmen, dass es ein riesiger Aufwand ist, den Pfad jeder neuen Binärdatei in einen absoluten Pfad des verschachtelten Systems umzuschreiben.

Kennt jemand eine sauberere Möglichkeit, einen benutzerdefinierten Bibliothekspfad einschließlich einer benutzerdefinierten ld-linux.so zu verwenden?

Datenlos
quelle

Antworten:

12

Der Pfad zum Loader wird in die Binärdatei kompiliert, wie Sie mit Ihrem Hex-Editor festgestellt haben. Du hast tatsächlich Glück gehabt, dass das Bearbeiten der Binärdatei direkt funktioniert hat, weil beide /lib/ld-linux.so.2und /home/chroot/ld.sodie gleiche Länge haben. Die Länge dieser Zeichenfolgen ist auch in der Binärdatei angegeben. Wenn Sie die Zeichenfolgen direkt ändern, können geringfügige Probleme auftreten.

Wenn Sie sich auf den Weg machen, sollten Sie sich etwas wie patchelf ansehen , um den Interpreter zu aktualisieren. Auf diese Weise können Sie den Interpreter schnell und sicher dauerhaft ändern.

gmjosack
quelle
War kein Glück, ich wusste, dass ich keines der Bytes verschieben musste ;-) Aber Patchelf sieht aus wie genau das, was ich will. Abgesehen davon, dass ich keinen relativen Pfad verwenden kann, kann er auch den LD_LIBRARY_PATH berücksichtigen, den ich verwende, sodass ich keinen Wrapper benötige. Ich werde die Antwort gutschreiben, sobald ich die Gelegenheit habe, sie zu testen.
Datum
1
Es klappt! Dies gibt mir einen guten Weg, um new-libc-Programme mit den old-libc-Programmen auf diesem Server zu mischen. Für zukünftige Leser lautete der Befehl patchelf --set-interpreter $JAVA/lib/ld-linux.so.2 --set-rpath $JAVA/lib:$JAVA/lib/i386:$JAVA/lib/i386/jli $JAVA/bin/java, wobei $ JAVA das Verzeichnis der JRE ist und ich alle abhängigen Bibliotheken aufgerundet und in das lib/Verzeichnis der JRE gestellt hatte.
Datum
Ich brauche noch LD_LIBRARY_PATH, um diese libjvm.so zu umgehen, da libstdc ++. so.6: Shared Object-Datei kann nicht geöffnet werden: Keine solche Datei oder Verzeichnis [root @ 97245bbe7cc1 tensorflow-java] #
Amos
@Amos Es ist schon eine Weile her, aber für meinen Fall habe ich LD_LIBRARY_PATH nicht mehr benötigt, da der Standard aus der Java-Binärdatei stammt. Beachten Sie jedoch den Teil, in dem ich sagte, dass ich herumgegangen bin und alle von Java verwendeten Bibliotheken gefunden und in das Java-Bibliotheksverzeichnis kopiert habe. Früher habe ich das ldd $JAVA/bin/javabekommen. Es gibt auch einige dynamische libc, die Sie brauchen, wie libnss.so
Datum