OSX中的协同设计和内核扩展(Kext):无法加载

时间:2013-03-27 11:28:05

标签: xcode macos code-signing codesign kernel-extension

我正在开发一个包含内核扩展的产品,并且在我们的一台测试机器中发现了一个奇怪的问题,我无法找到解决方案。

在我的开发机器中,(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(OSX 10.7.5与Xcode 3.2.6,Darwin Kernel 11.4.2 x86_64)时,它拒绝这样做:

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 kexts以向后兼容的方式签名。某些10.6和10.7内核无法加载x64和混合arch kexts,因为它们不了解嵌入到二进制文件中的签名。

codesign 命令行工具为此目的有一个未记录的 - no-macho 标志,但似乎没有实现。

更新2

问题仍然存在,如Xcode 4.6.2 4.6.3

2 个答案:

答案 0 :(得分:3)

序言:解释正在发生的事情

较旧的内核链接器/加载器无法处理kext的Mach-O对象代码中的某些类型的加载命令,包括LC_CODE_SIGNATURE部分。这也引起了例如问题。使用Xcode 4.5.x构建的混合32位/ 64位kexts,其中工具链添加了Lion和Snow Leopard内核链接器不期望的各种其他部分。 (this bug已在4.6.x中修复)

Apple尚未发布任何有关我可以找到的协同代码的具体信息。如果你看看他们自己的kexts,有些是签名的,有些则不是。 (据我所知,开源代码似乎是无符号的)如果您查看二进制文件中的Mach-O部分以获取其签名的kexts(使用otool -l),您会注意到LC_CODE_SIGNATURE不存在,与.app捆绑二进制文件不同,此内联签名现在是默认签名。甚至对于Mountain Lion附带的kexts也是如此。

因此,支持旧版本的解决方案是将签名放在单独的文件中,而不是让代码签名将签名部分插入到二进制文件中。

<强>解决方案

我找到了未记录的--no-macho标志in the codesign source code,这似乎可以解决问题。没有LC_CODE_SIGNATURE部分,签名最终在_CodeSignature/CodeSignature

答案 1 :(得分:1)

我相信解决方案可以在OS X文档中的新功能OS X v10.9 Mavericks页面底部的BSD和内核功能部分下找到。不幸的是,我不确定我是否可以在此公开这些信息,因为它属于预发布类别。但是,对于那些拥有付费Mac Dev帐户的人来说,这里是URL:

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