1
votes

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

2
looks like I'll better report a bug to Apple ...asr
Apple has closed this bug report as duplicated.asr
did u ever find a solution to this?vikram

2 Answers

3
votes

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.

1
votes

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