thiết kế mã và phần mở rộng hạt nhân (Kext) trong OSX: Sẽ không tải (codesign and kernel extension (Kext) in OSX: Won't load)


問題描述

thiết kế mã và phần mở rộng hạt nhân (Kext) trong OSX: Sẽ không tải (codesign and kernel extension (Kext) in OSX: Won't load)

I'm developing a product that includes kernel extension and have found a weird problem in one of our testing machines that I can't find a solution for.

In my development machine, (OSX 10.8.3 and latest Xcode) I codesign our kext like this:

$ codesign ‑s "Developer ID Application: Mycompany" my.kext
my.kext: signed bundle with Mach‑O thin (x86_64) [com.mycompany.kext]

it all goes fine, my.kext/Contents/MacOS/mykext binary is modified (signature added) and a folder my.kext/Contents/_CodeSignature is created with a file CodeResources in it.

When loading this kext on one of our testing machines (OSX 10.7.5 with Xcode 3.2.6, Darwin Kernel 11.4.2 x86_64), it refuses to do so:

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).

If I load the module unsigned, there is no problem. Also tried signing the kext from Xcode and not from command‑line, with the same results.

I moved the signing certificate to that troublesome computer, and signed the kext there. The signing process goes different:

$ codesign ‑v ‑s "Developer ID Application: Mycompany" my.kext
my.kext: signed bundle with generic [com.mycompany.kext]

Once signed, the kext executable at my.kext/Contents/MacOS/mykext is unmodified, and the folder Contents/_CodeSignature includes more files: CodeDirectory, CodeRequirements, CodeResources and CodeSignature. This signed kext seems to work on all devices so far.

So the question is: 

What's going on in here? What am I doing wrong in my signing process? How can I create a signature in a updated device that will work on this "outdated" machine? I understand that the target machine is refusing load of the kext because it does not undertand the signed binary. Signing from this device creates some kind of detached signature where the binary is untouched. I can't get my codesign to do that, the ‑D option seems useless and won't create a _CodeSignature folder inside the bundle. 

Update

As of XCode 4.6, the problem still persists. Only i386 kexts are signed in a backwards‑compatible way. x64 and mixed arch kexts can't be loaded by some 10.6 and 10.7 kernels due to them not understanding the signature embedded into the binaries.

The codesign command‑line tool has an undocumented ‑‑no‑macho flag for this purpose, but seems to be unimplemented.

Update 2

The problem still persists as of Xcode 4.6.2 4.6.3


參考解法

方法 1:

Preamble: Explanation of what's going on

The older kernel linker/loaders can't handle certain types of load commands in the kext's Mach‑O object code, including the LC_CODE_SIGNATURE section. This has also caused problems with e.g. mixed 32‑bit/64‑bit kexts built using Xcode 4.5.x, where the toolchain added various other sections that the Lion and Snow Leopard kernel linkers weren't expecting. (this bug is fixed in 4.6.x)

Apple hasn't released any specific info on codesigning kexts that I can find. If you look at their own kexts, some are signed, and some are not. (the open source ones seem to be unsigned as far as I can tell) If you look at the Mach‑O sections in the binaries for their signed kexts (using otool ‑l), you will notice that LC_CODE_SIGNATURE is absent, unlike .app bundle binaries, where this inline signature is now the default. This is the case even for kexts that ship with Mountain Lion.

So the solution for supporting older versions is to place the signature in a separate file rather than letting codesign insert a signature section into the binary.

Solution

I found the undocumented ‑‑no‑macho flag in the codesign source code and that seems to do the trick. No LC_CODE_SIGNATURE section, and the signature ends up in _CodeSignature/CodeSignature.

方法 2:

I believe the solution can be found under the BSD and Kernel Features section at the bottom of the OS X v10.9 Mavericks page in the What's New in OS X document. Unfortunately, I'm not sure if I can disclose the information here as it falls under the pre‑release category. However, for those of you who have a paid Mac Dev account, here's the URL:

https://developer.apple.com/library/prerelease/mac/releasenotes/MacOSX/WhatsNewInOSX/Articles/MacOSX10_9.html#//apple_ref/doc/uid/TP40013207‑CH100

(by asrpmdjahuang)

參考文件

  1. codesign and kernel extension (Kext) in OSX: Won't load (CC BY‑SA 3.0/4.0)

#XCode #code-signing #kernel-extension #macos #codesign






相關問題

卸載 xcode 4.5 (iOS 6) (Uninstall xcode 4.5 (iOS 6))

uitextview 字體不隨 fontWIthName 改變 (uitextview font not changing with fontWIthName)

如何將以下行添加到我的 plist 文件中? (How can I add the following lines to my plist file?)

XCode 4.6 顯示方法 + (void)beginAnimations:(NSString *)animationID context:(void *)context; 的內存洩漏警告 (XCode 4.6 shows a warning of memory leak for method + (void)beginAnimations:(NSString *)animationID context:(void *)context;)

iPhone SDK:檢查 UITableView 中每個對象的 ID 號並相應地更改徽章號 (iPhone SDK: Checking the ID number for each object in a UITableView and change the badge number accordingly)

畫面區域的選擇 (Selection of screen area)

如何更改主視圖是基於導航的應用程序! (how to change main view is navigation based app!)

Cocos2d 中的粒子碰撞檢測 (Collision detection with particles in Cocos2d)

Xcode Playground 只能部分運行 (Xcode Playground can only run partially)

如何為collectionviewcell的刪除自定義動畫? (How to custom animation for collectionviewcell's deletion?)

將 2 位整數分配給 char 變量 (Assigning a 2 digit integer to a char variable)

Xcode 12.5 (12E262) 在將 .scn 文件添加到 ARKit 項目後,“Command CodeSign 失敗,退出代碼為非零” (Xcode 12.5 (12E262) "Command CodeSign failed with a nonzero exit code" after a .scn file added to ARKit project)







留言討論