對各種二進位制格式的核心支援 (binfmt_misc)

此核心功能允許您透過在 shell 中簡單地鍵入其名稱來呼叫幾乎所有程式(有關限制,請參見下文)。 這包括例如已編譯的 Java(TM)、Python 或 Emacs 程式。

要實現這一點,您必須告訴 binfmt_misc 哪個直譯器必須用哪個二進位制檔案呼叫。 Binfmt_misc 透過將檔案開頭的某些位元組與您提供的魔術位元組序列(遮蔽掉指定的位)進行匹配來識別二進位制檔案型別。 Binfmt_misc 還可以識別檔名副檔名,例如 .com.exe

首先,您必須掛載 binfmt_misc

mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc

要實際註冊新的二進位制型別,您必須設定一個類似於 :name:type:offset:magic:mask:interpreter:flags 的字串(您可以根據需要選擇 :),並將其回顯到 /proc/sys/fs/binfmt_misc/register

以下是欄位的含義

  • name

    是一個識別符號字串。 將在此名稱下建立新的 /proc 檔案,位於 /proc/sys/fs/binfmt_misc 下; 由於顯而易見的原因,不能包含斜槓 /

  • type

    是識別的型別。 對於魔術,給出 M,對於副檔名,給出 E

  • offset

    是以位元組為單位的檔案中 magic/mask 的偏移量。 如果您省略它,則預設為 0(即,您編寫 :name:type::magic...)。 使用檔名副檔名匹配時將被忽略。

  • magic

    是 binfmt_misc 正在匹配的位元組序列。 魔術字串可能包含十六進位制編碼的字元,如 \x0a\xA4。 請注意,您必須轉義任何 NUL 位元組; 解析會在第一個 NUL 位元組處停止。 在 shell 環境中,您可能需要編寫 \\x0a 以防止 shell 吞噬您的 \。 如果您選擇了檔名副檔名匹配,則這是要識別的副檔名(不帶 .,不允許使用 \x0a 特殊字元)。 副檔名匹配區分大小寫,並且不允許使用斜槓 /

  • mask

    是一個(可選,預設為 all 0xff)掩碼。 您可以透過提供像魔術字串一樣長並且與魔術字串類似的字串來遮蔽掉一些匹配位。 掩碼與檔案的位元組序列進行與運算。 請注意,您必須轉義任何 NUL 位元組; 解析會在第一個 NUL 位元組處停止。 使用檔名副檔名匹配時將被忽略。

  • interpreter

    是應該以二進位制檔案作為第一個引數呼叫的程式(指定完整路徑)

  • flags

    是一個可選欄位,用於控制直譯器呼叫的多個方面。 它是大寫字母的字串,每個字母控制著某個方面。 支援以下標誌

    P - preserve-argv[0]

    binfmt_misc 的舊行為是使用二進位制檔案的完整路徑覆蓋原始的 argv[0]。 當包含此標誌時,binfmt_misc 將為此目的向引數向量新增一個引數,從而保留原始的 argv[0]。 例如,如果您的 interp 設定為 /bin/foo,並且您執行 blah(位於 /usr/local/bin 中),則核心將執行 /bin/foo,並將 argv[] 設定為 ["/bin/foo", "/usr/local/bin/blah", "blah"]。 interp 必須知道這一點,以便它可以執行 /usr/local/bin/blah,並將 argv[] 設定為 ["blah"]

    O - open-binary

    binfmt_misc 的舊行為是將二進位制檔案的完整路徑作為引數傳遞給直譯器。 當包含此標誌時,binfmt_misc 將開啟檔案以進行讀取,並將其描述符作為引數傳遞,而不是傳遞完整路徑,從而允許直譯器執行不可讀的二進位制檔案。 應該謹慎使用此功能 - 必須信任直譯器不會發出不可讀二進位制檔案的內容。

    C - credentials

    當前,binfmt_misc 的行為是根據直譯器計算新程序的憑據和安全令牌。 當包含此標誌時,這些屬性將根據二進位制檔案計算。 它也暗示了 O 標誌。 應該謹慎使用此功能,因為當執行由 root 擁有的 setuid 二進位制檔案時,直譯器將以 root 許可權執行。

    F - fix binary

    binfmt_misc 的通常行為是在呼叫 misc 格式檔案時延遲生成二進位制檔案。 然而,這在面對掛載名稱空間和 changeroot 時效果不佳,因此 F 模式會在安裝模擬後立即開啟二進位制檔案,並使用開啟的影像來生成模擬器,這意味著一旦安裝,無論環境如何變化,它始終可用。

有一些限制

  • 整個註冊字串不得超過 1920 個字元

  • magic 必須位於檔案的前 128 個位元組中,即 offset+size(magic) 必須小於 128

  • 直譯器字串不得超過 127 個字元

要使用 binfmt_misc,您必須首先掛載它。 您可以使用 mount -t binfmt_misc none /proc/sys/fs/binfmt_misc 命令掛載它,或者您可以將一行 none  /proc/sys/fs/binfmt_misc binfmt_misc defaults 0 0 新增到您的 /etc/fstab,以便它在啟動時自動掛載。

您可能需要在啟動期間的某個 /etc/rc 指令碼中新增二進位制格式。 閱讀您的 init 程式的手冊,以瞭解如何正確執行此操作。

考慮新增條目的順序! 稍後新增的條目將首先匹配!

一些示例(假設您位於 /proc/sys/fs/binfmt_misc 中)

  • 啟用對 em86 的支援(類似於 binfmt_em86,僅適用於 Alpha AXP)

    echo ':i386:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x03:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:' > register
    echo ':i486:M::\x7fELF\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x06:\xff\xff\xff\xff\xff\xfe\xfe\xff\xff\xff\xff\xff\xff\xff\xff\xff\xfb\xff\xff:/bin/em86:' > register
    
  • 啟用對打包的 DOS 應用程式的支援(預配置的 dosemu hdimage)

    echo ':DEXE:M::\x0eDEX::/usr/bin/dosexec:' > register
    
  • 啟用對使用 wine 的 Windows 可執行檔案的支援

    echo ':DOSWin:M::MZ::/usr/local/bin/wine:' > register
    

有關 java 支援,請參見 Java(tm) 二進位制核心 Linux 支援 v1.03

您可以透過將 0(停用)或 1(啟用)回顯到 /proc/sys/fs/binfmt_misc/status/proc/.../the_name 來啟用/停用 binfmt_misc 或一個二進位制型別。 Catting 檔案會告訴您 binfmt_misc/the_entry 的當前狀態。

您可以透過將 -1 回顯到 /proc/.../the_name/proc/sys/fs/binfmt_misc/status 來刪除一個條目或所有條目。

提示

如果您想將特殊引數傳遞給您的直譯器,您可以為其編寫一個包裝指令碼。 有關示例,請參見 Documentation/admin-guide/java.rst

您的直譯器不應在 PATH 中查詢檔名; 核心將傳遞給它要使用的完整檔名(或檔案描述符)。 使用 $PATH 可能會導致意外的行為,並且可能存在安全隱患。

Richard Günther <rguenth@tat.physik.uni-tuebingen.de>