【问题标题】:codesign and kernel extension (Kext) in OSX: Won't loadOSX 中的代码设计和内核扩展 (Kext):不会加载
【发布时间】:2013-03-27 11:28:05
【问题描述】:

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

在我的开发机器(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。

在我们的一台测试机器(OSX 10.7.5 和 Xcode 3.2.6,Darwin Kernel 11.4.2 x86_64)上加载这个 kext 时,它拒绝这样做:

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 和混合的 arch kext,因为它们不理解嵌入到二进制文件中的签名。

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

更新 2

从 Xcode 4.6.2 4.6.3

开始,问题仍然存在

【问题讨论】:

  • 看来我最好向 Apple 报告一个错误...
  • Apple 已将此错误报告视为重复而关闭。
  • 你找到解决办法了吗?

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


【解决方案1】:

序言:解释发生了什么

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

Apple 尚未发布任何我能找到的关于代码签名 kext 的具体信息。如果您查看他们自己的 kext,有些已签名,有些未签名。 (据我所知,开源的似乎没有签名)如果您查看二进制文件中的 Mach-O 部分的签名 kexts(使用 otool -l),您会注意到 LC_CODE_SIGNATURE 不存在,不像.app 捆绑二进制文件,此内联签名现在是默认值。即使是与 Mountain Lion 一起发布的 kext 也是如此。

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

解决方案

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

【讨论】:

  • 谢谢,这听起来不错。但我似乎无法让它工作。我在前面的命令行中添加了 --no-macho ,它似乎什么也没做。二进制文件仍在修改中,没有任何变化。
  • 我下载了代码,虽然它理解 --no-macho 参数,但它实际上并没有用它做任何事情。
  • 升级到 Xcode 4.6 成功了。似乎我什至不需要指定 --no-macho 标志,默认情况下 kext 被签名为“通用”并且二进制文件没有被修改。我遇到的另一个问题(由于另一个无效部分而无法加载 i386 kext)也已修复。
  • @asr 你用的是 4.5?是的,那个版本对 kexts 来说是个坏消息。
  • @asr 你能总结一下你现在有什么设置,什么有效,什么无效?此外,对于非工作,如果插入签名部分,您可以与otool -l 检查吗?我可以确认 codesigning kexts 可以与 Xcode 4.4.1 命令行实用程序一起使用,而使用 Xcode 4.5 构建的 i386 kexts 不能(无论 codesigning 是什么)。
【解决方案2】:

我相信可以在 What's New in 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-19
    • 2016-09-15
    • 2013-06-16
    • 2014-02-17
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多