具有有效签名的 macOS Kext 在第二次安装后被拒绝(高 sierra)



在之前安装过我的产品的机器中,由于 kext 签名被拒绝,第二次安装失败。

我在某些地方看到了相同的错误,例如这里:https://support.eset.com/kb6570,但是即使在恢复模式下清除kext_policy表并在设置中手动批准 kext -->下次启动的安全性后,kext 似乎仍然未被批准。

例如,运行 kextutil 可提供以下内容:

Kalyan:~ KalyanPentakota$ sudo kextutil /Library/Extensions/mycompanyAT.kext/
Password:
Kext rejected due to insecure location: <OSKext 0x7f8e9ff02e20 [0x7fffa11c8af0]> { URL = "file:///Library/StagedExtensions/Library/Extensions/mycompanyAT.kext/", ID = "com.mycompany.at" }
Kext rejected due to insecure location: <OSKext 0x7f8e9ff02e20 [0x7fffa11c8af0]> { URL = "file:///Library/StagedExtensions/Library/Extensions/mycompanyAT.kext/", ID = "com.mycompany.at" }
Diagnostics for /Library/Extensions/mycompanyAT.kext:

数据库中的 KEXT 审批状态:

sqlite> select * from kext_policy;
XE2XNRRXZ5|jp.co.canon.bj.print.BJUSBLoad|1|Canon Inc.|8
KBVSJ83SS9|com.citrix.kext.gusb|1|Citrix Systems, Inc.|8
MK9BR98H51|com.mycompany.at|1|My Company Ltd|1

Kext 证书验证:

Kalyan:~ KalyanPentakota$ codesign -dvv /Library/Extensions/mycompanyAT.kext/
Executable=/Library/Extensions/mycompanyAT.kext/Contents/MacOS/mycompanyAT
Identifier=com.mycompany.at
Format=bundle with Mach-O thin (x86_64)
CodeDirectory v=20200 size=8179 flags=0x0(none) hashes=250+3 location=embedded
Signature size=4651
Authority=Developer ID Application: My Company Ltd (MK9BR98H51)
Authority=Developer ID Certification Authority
Authority=Apple Root CA
Signed Time=Jun 5, 2018 at 6:05:21 AM
Info.plist entries=22
TeamIdentifier=MK9BR98H51
Sealed Resources version=2 rules=13 files=1
Internal requirements count=1 size=212

我也尝试删除/Library/StagedExtensions/Library/,但它也没有改变任何东西。

我遇到了同样的问题。

/Library/StagedExtensions 的标志必须被"限制":

ls -laO /Library/StagedExtensions/

drwxr-xr-x@ 4根轮限制 128 Nov 15 2017 分阶段扩展

如果没有,请从恢复模式尝试以下cmd:

chflags -R restricted /V*/*/Library/StagedExtensions

重新启动并尝试安装 kext。

此解决方法目前解决了我们在生产中遇到的所有情况:

您应该在恢复模式下加载,禁用 sip,重新启动,使 kext 缓存失效,再次在恢复中重新启动,然后重新启用 sip。

详细步骤:

  1. 从苹果菜单中选择重新启动。
  2. 当 Mac 重新启动时,在听到启动提示音后立即按住 Command(⌘) + R 键。按住按键,直到出现Apple徽标以使计算机处于恢复模式。
  3. 计算机现在处于恢复模式。从 Apple 菜单中选择实用程序 ->终端
  4. 运行命令:CSRuTurt 禁用
  5. 从苹果菜单中,选择重新启动。
  6. 加载 macOS 后,打开终端并键入:sudo kextcache -invalid/
  7. 如果您的 kext
  8. 位于非标准位置,请添加自定义 kext 路径,例如:
    sudo kextcache -invalid/Library/MyApp/MyApp.kext
  9. 从苹果菜单中,选择重新启动。
  10. Mac 重新启动时,按住 Command(⌘) + R 键 听到启动铃声后立即响起。按住按键直到 苹果徽标出现,使计算机处于恢复模式。
  11. 计算机现在处于恢复模式。从苹果菜单中选择 公用设施 ->终端
  12. 运行命令:csrutil enable
  13. 从苹果菜单中,选择重新启动。
  14. 现在你的 kext 应该运行了..

更新

现在至少有一个可能导致该问题的原因完全已知,请参阅下面的更新更新 (2020-04-10)


恕我直言,Kext rejected due to insecure location不是签名拒绝。它在哪里说了关于签名的内容?当签名是问题时,文学上是这样说的。对我来说,这条消息说这个位置不安全。

您是否检查了/Library/Extensions的访问权限?如果权限太开放,系统将拒绝加载带有kextloadkextutil的内核扩展。文件夹/Library/Extension必须归root:wheel所有,并且除了root之外,任何人都不能写入该文件夹。

扩展的访问权限也是如此,扩展是捆绑包(.kext),因此实际上是目录。它们必须归root:wheel所有,并且只有root才能对它们具有写入权限。

如果你看一下macOS的源代码(是的,macOS是广泛的开源,人们往往会忘记这一点),你会发现这个错误只在一个地方被抛出:

if (authOptions->requireSecureLocation) {
if (!kextIsInSecureLocation(theKext)) {
OSKextLogCFString(NULL,
kOSKextLogErrorLevel | kOSKextLogValidationFlag,
CFSTR("Kext rejected due to insecure location: %@"),
theKext);
result = false;
goto finish;
}
}

现在kextIsInSecureLocation()非常简单:

Boolean
kextIsInSecureLocation(OSKextRef theKext)
{
NSURL *url = (__bridge NSURL *)OSKextGetURL(theKext);
if (!url) {
return false;
}
return pathIsSecure(url.path);
}

pathIsSecure()也是如此:

Boolean
pathIsSecure(NSString *path) {
Boolean is_secure = false;
BOOL is_protected_volume = rootless_protected_volume(path.UTF8String) ? YES : NO;
BOOL is_trusted_path = rootless_check_trusted_class(path.UTF8String, "KernelExtensionManagement") == 0 ? YES : NO;
if (isSIPDisabled()) {
// SIP is disabled so everything is considered secure.
is_secure = true;
} else if (!is_protected_volume) {
// SIP is enabled and the volume is not protected, so it's insecure.
is_secure = false;
} else {
// SIP is enabled and it is a protected volume, so it's only secure if it's trusted.
is_secure = is_trusted_path;
}
return is_secure;
}

因此,禁用 SIP 后,任何路径都是安全的,启用 SIP 后,没有 SIP 支持的卷永远不会安全,否则似乎有一个受信任路径的列表,我确信/Library/Extensions是这样的受信任路径,但前提是其权限设置正确。

要检查您的卷是否支持 SIP,请打开Disk Utility应用程序,选择您的启动卷并点击CMD+I。将打开一个窗口,其中列出了所有类型的属性,其中应该有一个说法:

System Integrity Protection supported : Yes

如果它说不,你肯定会有问题,但我不知道哪一个,因为不知道没有办法为单个卷 en-/禁用 SIP,我只是想象某些文件系统或通过网络挂载的卷可能无法支持 SIP。

更新 (2018-07-31)

就此联系Apple,他们给了我以下提示:

另外,如果有用,sudo kextcache --clear-staging允许用户清除/Library/StagedExtensions文件夹 无需启动恢复。

不确定这是否解决了类似情况下的问题,只需在此处与您分享此信息。

更新 (2020-04-10)

显然,ls -alO@u /Library/Extensions的输出应如下所示:

drwxr-xr-x 5 root wheel restricted 160 Oct 24 12:18 .
drwxr-xr-x@ 3 root wheel restricted 96 Mar 25 13:00 ..
com.apple.rootless 25
drwxr-xr-x 15 root wheel restricted 480 Oct 24 12:18 Extensions

然而,在某些受影响的系统上,它看起来像这样:

drwxr-xr-x 4 root wheel - 128 Apr 6 18:58 .
drwxr-xr-x 3 root wheel - 96 Apr 6 18:56 ..
drwxr-xr-x 13 root wheel - 416 Apr 6 18:57 Extensions

如您所见,缺少com.apple.rootless文件属性,并且文件夹未标记为restricted请注意,这是启用了SIP的系统输出,并且用户从未自己禁用过它。

不幸的是,恢复该属性是不可能的。该属性的值为:

# xattr -p com.apple.rootless /Library/StagedExtensions
KernelExtensionManagement

但即使禁用了 SIP,以下命令也会失败:

sudo xattr -w com.apple.rootless KernelExtensionManagement 
/Library/StagedExtensions

它返回[Errno 1] Operation not permitted.因此,如果其中一个变通技巧不起作用,其他人已经在这里发布(对于某些人来说,它们都不起作用!),请准备好重新设置您的系统,因为它严重损坏,这不是您的错,但Apple在这里没有提供任何帮助。

最新更新