Debian

$LIB 變數不會擴展到 Ubuntu Server 18.10 中的任何內容

  • January 15, 2019

我有與之前發布的這個問題相同的問題,其中/etc/ld.so.preload不攔截正確的架構。一點背景知識:我編譯了一個共享對象(64 位),它ld.so.preload在任何二進制執行的文件中都被引用。問題是我ERROR: ld.so: object '/usr/local/lib/mysharedobject.so' from /etc/ld.so.preload cannot be preloaded (wrong ELF class: ELFCLASS64): ignored.在執行 32 位程序時遇到了問題。

要根據該問題的答案解決問題,我必須創建兩個目錄(例如 in )lib/i386-linux-gnu並指定in ,以便根據程序架構預載入正確的庫。 x86_64-linux-gnu``/var/opt``/var/opt/$LIB/mysharedobject.so``/etc/ld.so.preload

因此,在這種情況下,在基於 Debian 的系統中,/var/opt/$LIB/mysharedobject.so將擴展為:

  • /var/opt/lib/i386-linux-gnu/mysharedobject.so對於 32 位程序;
  • /var/opt/x86_64-linux-gnu/mysharedobject.so對於 64 位程序。

但是,應用此功能後,我執行的任何二進製文件(例如ls)都將輸出以下“錯誤”:

ERROR: ld.so: object '/var/opt/$LIB/mysharedobject.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.

如您所見,$LIB 沒有擴展到任何東西。我還設置並執行$LD_LIBRARY_PATH以使用此庫更新系統,但沒有成功。這裡有什麼問題?/var/opt``ldconfig

終於解決了問題。$LIB環境變數擴展到lib3232 位程序和lib/x86_64-linux-gnu64 位程序的目錄(如/usr/$LIB/mysharedlibrary.so/etc/ld.so.preload) - 如中所示strace。這適用於基於 Debian 的系統,對於其他系統,它將擴展到lib64lib(總是可以用 來確認strace,更具體地說是openat()系統呼叫)。

因此解決方案是使用兩者編譯共享庫,-m32並將-m64相關架構文件從$LIB.

總結(範例):

$ mkdir {32,64}
$ gcc -Wall -m32 -fPIC -shared -o 32/mysharedlibrary.so mysharedlibrary.c -ldl
$ gcc -Wall -fPIC -shared -o 64/mysharedlibrary.so mysharedlibrary.c -ldl
$ sudo mv 32/mysharedlibrary.so /usr/lib32/mysharedlibrary.so
$ sudo mv 64/mysharedlibrary.so /usr/lib/x86_64-linux-gnu/mysharedlibrary.so
$ sudo echo '/usr/$LIB/mysharedlibrary.so' > /etc/ld.so.preload

shell會擴展**$LIB**,但是當你這樣做時這是不可能的:

指定**/var/opt/$LIB/mysharedobject.so/etc/ld.so.preload**

提到的手冊頁**/etc/ld.so.preload**沒有提到全域擴展或環境變數的可能性:

包含要在程序之前載入的 ELF 共享對象的空格分隔列表的文件。見**LD_PRELOAD上面的討論。如果同時使用LD_PRELOAD**和 /etc/ld.so.preload,則首先預載入由 指定的庫 LD_PRELOAD。 **/etc/ld.so.preload**具有系統範圍的效果,導致為系統上執行的所有程序預載入指定的庫。(這通常是不可取的,並且通常僅用作緊急補救措施,例如,作為庫配置錯誤問題的臨時解決方法。)

當您停下來思考如何使用數據時,這也不太可能:

  • glob-expansions 將是一個安全問題,因為數據(不明確)可以匹配各種有趣的文件,並且
  • 環境變數必須設置在某個地方,並且對於不同的使用者來說很容易不同。

現在……手冊頁提到**$LIB**可以在 rpath 和 中使用LD_PRELOAD,但它也說

在安全執行模式下,包含斜杠的預載入路徑名將被忽略。 此外,共享對象僅從標準搜尋目錄中預載入,並且僅在它們啟用了 set-user-ID 模式位時(這不是典型的)。

這是一個會影響您的陷阱,因為它**/var/opt**可能不是標準的搜尋目錄。

引用自:https://unix.stackexchange.com/questions/493364