2013-03-27 6 views
1

Я разрабатываю продукт, который включает расширение ядра и обнаружил странную проблему на одной из наших тестовых машин, для которой я не могу найти решение.codeign и расширение ядра (Kext) в OSX: не загружается

В моей машине развития (OSX 10.8.3 и последняя Xcode) Я CodeSign наш 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). 

Если я загружаю модуль без знака, нет проблем. Также попытался подписать kext из Xcode, а не из командной строки, с теми же результатами.

Я переместил сертификат подписи на этот сложный компьютер и подписал там kext. Процесс подписания идет иначе:

$ codesign -v -s "Developer ID Application: Mycompany" my.kext 
my.kext: signed bundle with generic [com.mycompany.kext] 

После подписания Kext исполняемого на my.kext/Содержание/MacOS/mykext не изменялся, а содержимое папки/_CodeSignature включает несколько файлов: CodeDirectory, CodeRequirements, CodeResources и CodeSignature. Этот подписанный kext, похоже, работает на всех устройствах до сих пор.

Так что вопрос:

Что здесь происходит? Что я делаю неправильно в процессе подписания? Как создать подпись в обновленном устройстве, которое будет работать на этой «устаревшей» машине? Я понимаю, что целевая машина отказывается от нагрузки kext, потому что она не поддерживает подписанный двоичный файл. Подписание с этого устройства создает какую-то выделенную подпись, где двоичный файл не тронут. Я не могу получить свой код для этого, опция -D кажется бесполезной и не будет создавать папку _CodeSignature внутри пакета.

Обновление

По состоянию XCode 4.6, проблема все еще сохраняется. Только i386 kexts подписаны обратно совместимым способом. x64 и смешанные арки kexts не могут быть загружены некоторыми ядрами 10.6 и 10.7 из-за того, что они не понимают подпись, встроенную в двоичные файлы.

CodeSign инструмент командной строки имеет недокументированные --no-мачо флаг для этой цели, но, кажется, невыполненными.

Update 2

проблема все еще сохраняется, как в Xcode 4.6.2 4.6.3

+0

выглядит как я лучше сообщить об ошибке в Apple, ... – asr

+0

Apple, закрыл этот отчет об ошибке, как дублируется. – asr

+0

Вы когда-нибудь находили решение? – vikram

ответ

3

Преамбула: Объяснение того, что происходит на

Старшего ядра компоновщика/погрузчики не может обрабатывать определенные типы команд нагрузки в объектном коде Mach-O kext, включая раздел LC_CODE_SIGNATURE. Это также вызвало проблемы, например, смешанные 32-битные/64-битные kexts, построенные с использованием Xcode 4.5.x, где инструментальная цепочка добавила различные другие разделы, которые не ожидали линкеры Lion и Snow Leopard. (this bug зафиксировано в 4.6.x)

Apple не опубликовала никакой конкретной информации о кодах, указывающих kexts, которые я могу найти. Если вы посмотрите на свои собственные kexts, некоторые из них подписаны, а некоторые нет. (с открытым исходным кодом кажутся неподписанными, насколько я могу судить). Если вы посмотрите на разделы Mach-O в двоичных файлах для своих подписанных kexts (используя otool -l), вы заметите, что LC_CODE_SIGNATURE отсутствует, в отличие от .app бинарных файлов пакета, где эта встроенная подпись теперь по умолчанию. Это относится и к kexts, которые поставляются с Mountain Lion.

Таким образом, решение для поддержки более старых версий заключается в том, чтобы разместить подпись в отдельном файле, а не позволять кодовому коду вставлять раздел подписи в двоичный файл.

Решение

Я нашел недокументированные --no-macho флаг in the codesign source code и что, кажется, сделать трюк. Нет LC_CODE_SIGNATURE раздел, и подпись заканчивается в _CodeSignature/CodeSignature.

+0

Спасибо, это звучит здорово. Но я не могу заставить его работать. Я добавил --no-macho в предыдущую командную строку и, похоже, ничего не делает. Тем не менее бинарный файл изменяется, ничего не меняется. – asr

+0

Я загрузил код и, хотя он понимает аргумент --no-macho, на самом деле ничего не делает с ним. – asr

+0

Модернизация до Xcode 4.6 сделала трюк. Кажется, мне даже не нужно указывать флаг -no-macho, по умолчанию kext подписывается как «общий», а двоичный файл не изменяется. Также исправлена ​​и другая проблема, с которой я (i386 kext не загружается из-за другого недопустимого раздела). – asr

1

Я считаю, что решение можно найти в разделе BSD и Kernel Features в нижней части страницы OS X v10.9 Mavericks в «Что нового в документе OS X». К сожалению, я не уверен, могу ли я раскрывать информацию здесь, поскольку она подпадает под категорию до релиза. Тем не менее, для тех из вас, кто имеет платную Mac Dev счет, вот URL:

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