The ‘app’ you can’t trash: how SIP is broken in High Sierra

When you install something, you expect to be able to remove it too. But when a reader came to uninstall BlueStacks, an Android emulator, from his Mac running High Sierra 10.13.2, he found the way blocked. The Finder kindly informed him that “The operation can’t be completed because you don’t have the necessary permission.”

The moment that we see the word permission, all becomes clear: it’s a permissions problem. So the next step is to select the offending item in the Finder, press Command-I to bring up the Get Info dialog, and change the permissions. It does, though, leave the slight puzzle as to why the Finder didn’t simply prompt for authentication instead of cussedly refusing.

Sure enough, after trying that, the app still won’t go and the error message is unchanged.

Another strange thing about this ‘app’ is that it’s not an app at all. Tucked away in a mysterious folder, new to High Sierra, in /Library/StagedExtensions/Applications, its icon is defaced to indicate that the user can’t even run it. Neither did the user install it there.

Trying to remove it using a conventional Terminal command
sudo rm -rf /Library/StagedExtensions/Applications/BlueStacks.app
also fails, with the report Operation not permitted.

High Sierra leaves the user wondering what has happened. There’s nothing in Apple’s scant documentation to explain how this strange situation has arisen, and seemingly nothing more that the user can do to discover what is wrong, or to do anything about it.

The clue comes from probing around in Terminal, specifically using a command like
ls -lO /Library

Try that in High Sierra, and you’ll see
drwxr-xr-x@ 4 root wheel restricted 128 2 Jan 13:03 StagedExtensions

There are two relevant pieces of information revealed: the @ sign shows that directory has extended attributes (xattrs), and the word restricted that it is protected by System Integrity Protection (SIP). A quick peek inside /Library/StagedExtensions/Applications/BlueStacks.app shows that it is a stub of an app, lacking any main code, but it does contain a kernel extension (KEXT) which is also protected by SIP, by virtue of being inside a SIP-protected folder.

> ls -lO /Library/StagedExtensions/Applications
drwxr-xr-x 3 root wheel restricted 96 2 Jan 13:03 BlueStacks.app

So how did this third-party kernel extension end up in this mysterious folder, complete with SIP protection? Surely SIP is there to protect macOS, not third-party app components installed later by the user? Who or what enabled SIP on that extension, and how can it be removed?

Perhaps not unsurprisingly, even Apple’s developer documentation doesn’t seem to answer any of those questions. So here is what I have been able to discover.

High Sierra has a new mechanism for handling third-party kernel extensions (User-Approved Kernel Extension Loading, or UAKL), which requires the user to authorise them. When a third-party installer tries to install a kernel extension, you see the warning

sipperms01

Assuming that you open Security preferences, you will there click on the Allow button to permit the extension to be loaded.

sipperms02

High Sierra then packages the extension in the form of a non-executable stub app, which it installs in /Library/StagedExtensions/Applications. What you see there looks like a mutated form of the app.

sipperms03

When you then try to remove the app proper, you and it will both think that it has gone for good.

sipperms04

But in truth, its kernel extension has been left in /Library/StagedExtensions/Applications/, looking just like an app.

In its infinite wisdom, Apple has given the folder /Library/StagedExtensions the full protection of SIP, by attaching a com.apple.rootless xattr to it.

sipperms05

My reading of that xattr is that only Apple’s KernelExtensionManagement service can give permission for changes to be made within that folder, and the folders within it.

So now the user cannot touch that residual extension, and they certainly can’t uninstall, move, or trash it. Until the user can gain access to that volume with its SIP inactive, that stub app and the extension inside it stay put. It has been suggested that macOS automatically cleans /Library/StagedExtensions, although I have yet to see any evidence of that occurring. Thus SIP prevents the user from uninstalling a third-party app which the user installed, even though the kernel extension might be rendering macOS unstable, or have other significant side-effects.

The solution is to restart in Recovery mode, and delete the stub app using Terminal there, with a command like
rm -rf /Volumes/Macintosh\ HD/Library/StagedExtensions/Applications/BlueStacks.app

You don’t need to alter SIP there, as SIP is only applied to the startup volume. As you have now started up from the Recovery volume, SIP no longer protects the contents of your normal startup volume.

This is such a good piece of security that, when some malware does manage to slip an evil kernel extension past a user and is rewarded with the protection of SIP, neither the user nor any anti-malware tool will be able to remove that extension, unless the user restarts from a different boot volume, or KernelExtensionManagement allows it.

Unless I’m missing something here, this doesn’t seem particularly good.

(Thanks to @Roller_ for the novel problem.)