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