Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

macOS Kext with valid signature rejected after 2nd installation (high sierra)

In a machine where my product was installed before, a second installation fails, due to kext signature rejection.

I have seen in some places the same error, for example here: https://support.eset.com/kb6570, however even after clearing the kext_policy table in recovery mode, and approving the kext manually in settings --> security in the next boot, the kext still appears to be unapproved.

For example, running kextutil provides the following:

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 approval status in database:

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 certificate validation:

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

I have also tried removing /Library/StagedExtensions/Library/, but it didn't change anything as well.

like image 267
IdoT Avatar asked Jun 17 '18 13:06

IdoT


3 Answers

I had the same issue.

The flag of /Library/StagedExtensions must be "restricted":

ls -laO /Library/StagedExtensions/

drwxr-xr-x@ 4 root wheel restricted 128 Nov 15 2017 StagedExtensions

If not, try below cmd from recovery mode:

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

Reboot and try installing the kext.

like image 181
7aadi Avatar answered Oct 30 '22 07:10

7aadi


Update

At least one possible cause of that issue is now exactly known, see update Update (2020-04-10) below


Kext rejected due to insecure location is no signature rejection IMHO. Where does it say anything about signature? When the signature is the problem, it literary says so. To me that message says the location is insecure.

Have you checked the access permissions of /Library/Extensions? If the permissions are too open, the system will refuse to load kernel extensions with kextload or kextutil. The folder /Library/Extension must be owned by root:wheel and nobody but root must be able to write to that folder.

Same holds true for the access permissions of extensions, which are bundles (.kext) and thus actually directories. They must be owned by root:wheel and only root may have write permission to them.

If you look at the source code of macOS (yes, macOS is widely OpenSource, people tend to forget that), you see that this error is thrown in just one place:

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

Now kextIsInSecureLocation() is very simple:

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

And so is 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;
}

So with SIP disabled, any path is secure, with SIP enabled, volumes w/o SIP support are never secure, otherwise there seems to be a list of trusted paths and I know for sure that /Library/Extensions is such a trusted path, yet only if its permission are set correctly.

To check if your volume supports SIP, open Disk Utility app, select your boot volume and hit CMD+I. A window opens that lists all kind of properties and among these should be one saying:

System Integrity Protection supported : Yes

If it says no, you definitely would have a problem, but I have no idea which one as no way to en-/disable SIP for individual volumes is known, I only imagine that certain file systems or volumes mounted over the network may not be able to support SIP.

Update (2018-07-31)

Contacting Apple about this, they gave me the following tip:

Also, in case it is useful, sudo kextcache --clear-staging allows a user to clear the /Library/StagedExtensions folder without booting into recovery.

Not sure if this solves the problem in similar cases, just sharing this information with you here.

Update (2020-04-10)

Apparently the output of ls -alO@u /Library/Extensions should look like this:

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

Yet on some affected systems it looks like this:

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

As you can see, the com.apple.rootless file attribute is missing and the folders are not marked restricted. Please note, that this is the output of a system that does have SIP enabled and where the user has never disabled it himself.

Unfortunately restoring that attribute is impossible. The value of that attribute is:

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

But even with disabled SIP, the following command will fails:

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

It returns [Errno 1] Operation not permitted. So if one of the work around tricks don't work that others have been posting here (and for some people none of them works!), be prepared to re-setup your system as it's seriously broken and that isn't your fault but Apple is not providing any help here.

like image 4
Mecki Avatar answered Oct 30 '22 06:10

Mecki


This workaround currently resolved all the cases we encountered in production:

You should load in recovery mode, disable sip, restart, invalidate kext cache, restart in recovery again and then re-enable sip.

Detailed steps:

  1. From the Apple menu select Restart.
  2. As your Mac restarts, press and hold down the Command(⌘) + R keys immediately upon hearing the startup chime. Hold the keys until the Apple logo appears to get the computer in Recovery mode.
  3. The computer is now in Recovery mode. From the Apple menu select Utilities -> Terminal
  4. Run the command: csrutil disable
  5. From the Apple menu, select Restart.
  6. After the macOS is loaded, open terminal and type: sudo kextcache -invalidate /
  7. if you your kext is located in non standard location, add the custom kext path, for example:
    sudo kextcache -invalidate /Library/MyApp/MyApp.kext
  8. From the Apple menu, select Restart.
  9. As your Mac restarts, press and hold down the Command(⌘) + R keys immediately upon hearing the startup chime. Hold the keys until the Apple logo appears to get the computer in Recovery mode.
  10. The computer is now in Recovery mode. From the Apple menu select Utilities -> Terminal
  11. Run the command: csrutil enable
  12. From the Apple menu, select Restart.
  13. Now your kext should run..
like image 3
IdoT Avatar answered Oct 30 '22 08:10

IdoT