カーネル拡張機能を含む製品を開発していますが、テスト マシンの 1 つで解決策が見つからない奇妙な問題を発見しました。
私の開発マシン (OSX 10.8.3 および最新の Xcode) では、次のように kext をコード署名します。
$ codesign -s "Developer ID Application: Mycompany" my.kext
my.kext: signed bundle with Mach-O thin (x86_64) [com.mycompany.kext]
すべてうまくいき、my.kext/Contents/MacOS/mykext バイナリが変更され (署名が追加され)、フォルダ my.kext/Contents/_CodeSignature が作成され、ファイル CodeResources が含まれます。
この kext をテスト マシン (Xcode 3.2.6 を搭載した OSX 10.7.5、Darwin Kernel 11.4.2 x86_64) の 1 つにロードすると、ロードが拒否されます。
kxld[com.mycompany.kext]: The Mach-O file is malformed: Invalid segment type in MH_KEXT_BUNDLE kext: 29.
Can't load kext com.mycompany.kext - link failed.
Failed to load executable for kext com.mycompany.kext.
Kext com.mycompany.kext failed to load (0xdc008016).
署名なしでモジュールをロードしても問題ありません。また、コマンドラインからではなく、Xcode から kext に署名しようとしましたが、同じ結果が得られました。
署名証明書をその面倒なコンピューターに移動し、そこで kext に署名しました。署名プロセスは異なります。
$ codesign -v -s "Developer ID Application: Mycompany" my.kext
my.kext: signed bundle with generic [com.mycompany.kext]
署名が完了すると、my.kext/Contents/MacOS/mykext にある kext 実行可能ファイルは変更されず、フォルダー Contents/_CodeSignature には、CodeDirectory、CodeRequirements、CodeResources、および CodeSignature というその他のファイルが含まれます。この署名された kext は、これまでのところすべてのデバイスで動作するようです。
質問は次のとおりです。
ここで何が起こっているのですか?署名プロセスで何が間違っていますか? この「古い」マシンで動作する更新されたデバイスで署名を作成するにはどうすればよいですか? 署名されたバイナリを理解していないため、ターゲット マシンが kext のロードを拒否していることを理解しています。このデバイスから署名すると、バイナリが変更されていない、ある種の切り離された署名が作成されます。-D オプションは役に立たないようで、バンドル内に _CodeSignature フォルダーを作成しません。
アップデート
XCode 4.6 の時点でも、問題は解決していません。下位互換性のある方法で署名されているのは、i386 kext のみです。一部の 10.6 および 10.7 カーネルでは、バイナリに埋め込まれた署名を理解できないため、x64 および混合アーキテクチャ kext をロードできません。
codesignコマンドライン ツールには、この目的のために文書化されていない--no-machoフラグがありますが、実装されていないようです。
更新 2
Xcode 4.6.2 4.6.3の時点でも問題は解決していません