xcode OSX 中的协同设计和内核扩展 (Kext):不会加载

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15657720/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 03:04:33  来源:igfitidea点击:

codesign and kernel extension (Kext) in OSX: Won't load

xcodemacoscode-signingcodesignkernel-extension

提问by asr

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:

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

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.

一切顺利,my.kext/Contents/MacOS/mykext 二进制文件被修改(添加了签名)并创建了一个文件夹 my.kext/Contents/_CodeSignature,其中包含一个文件 CodeResources。

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:

在我们的一台测试机器(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).

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.

如果我加载未签名的模块,则没有问题。还尝试从 Xcode 而不是从命令行签署 kext,结果相同。

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

我将签名证书移到那台麻烦的计算机上,并在那里签署了 kext。签署过程有所不同:

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

签名后,位于 my.kext/Contents/MacOS/mykext 的 kext 可执行文件未修改,文件夹 Contents/_CodeSignature 包含更多文件:CodeDirectory、CodeRequirements、CodeResources 和 CodeSignature。到目前为止,这个签名的 kext 似乎适用于所有设备。

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.

这里发生了什么?我在签名过程中做错了什么?如何在更新后的设备中创建可以在这台“过时”机器上使用的签名?我知道目标机器拒绝加载 kext,因为它不理解已签名的二进制文件。从此设备签名会创建某种分离的签名,其中二进制文件未受影响。我无法让我的 codesign 这样做,-D 选项似乎没用,并且不会在包中创建 _CodeSignature 文件夹。

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.

从 XCode 4.6 开始,问题仍然存在。只有 i386 kexts 以向后兼容的方式签名。一些 10.6 和 10.7 内核无法加载 x64 和混合架构 kext,因为它们不理解嵌入到二进制文件中的签名。

The codesigncommand-line tool has an undocumented --no-machoflag for this purpose, but seems to be unimplemented.

协同设计的命令行工具有一个无证--no-男子气用于此目的的标志,但似乎没有实现。

Update 2

更新 2

The problem still persists as of Xcode 4.6.24.6.3

从 Xcode 4.6.24.6.3 开始,问题仍然存在

回答by pmdj

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_SIGNATUREsection. 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 bugis fixed in 4.6.x)

较旧的内核链接器/加载器无法处理 kext 的 Mach-O 目标代码中的某些类型的加载命令,包括该LC_CODE_SIGNATURE部分。这也导致了一些问题,例如使用 Xcode 4.5.x 构建的混合 32 位/64 位 kext,其中工具链添加了 Lion 和 Snow Leopard 内核链接器没有预料到的各种其他部分。(此错误已在 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_SIGNATUREis absent, unlike .appbundle binaries, where this inline signature is now the default. This is the case even for kexts that ship with Mountain Lion.

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

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.

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

Solution

解决方案

I found the undocumented --no-machoflag in the codesign source codeand that seems to do the trick. No LC_CODE_SIGNATUREsection, and the signature ends up in _CodeSignature/CodeSignature.

在 codedesign 源代码中发现了未记录的--no-macho标志,这似乎可以解决问题。没有部分,签名以.LC_CODE_SIGNATURE_CodeSignature/CodeSignature

回答by ahuang

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:

我相信该解决方案可以在 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

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