Hello, I am working on app which must prevent attaching any USB devices to Mac due to security.
Unfortunately I have not found any direct way to implement such blocking:
- Looks like IOKit does not allow to block USB (at least in user space)
- ES_EVENT_TYPE_AUTH_IOKIT_OPEN (Endpoint Security) does not prevent using USB device if I send response ES_AUTH_RESULT_DENY for "AppleUSBHostDeviceUserClient"
I have found several similar problems on forum but no any solution: https://developer.apple.com/forums/thread/671193 (https://developer.apple.com/forums/thread/756573 https://developer.apple.com/forums/thread/741051
What is the easiest way to implement such blocking?
Thank you in advance!
Hi,
What is the easiest way to implement such blocking?
Starting with the bottom line question first, the big question I'd ask here is what you're actually trying to block and why. I'm not sure there is any good way to block "everything" at the USB layer and unless you that's REALLY what you want.
Looking at a few specifics:
Looks like IOKit does not allow to block USB (at least in user space)
The issue that comes up with IOKit is that many of our drivers (including USB) "exit" the kernel at multiple points. Typically, that means some combination of:
-One more more userclients at multiple "levels" of a given driver stack. On USB, there's a user clients against the IOUSBHostDevice itself, then (typically) one or more IOUSBHostInterface user clients.
-Depending on the actual device, the "exit" out of IOKit may be through a non-IOKit interface that isn't really "visible" through IOKit. For example, mass storage volume "end" at an IOMediaBSDClient, which leads to the dev node and then DiskArbitration volume mounting.
Strictly speaking, it is possible to block USB devices through the IOKit stack. You an use either of those user clients to obtain exclusive access, at which point "no one else" will be able to communicate with the device. The problem is that the details of what's ACTUALLY required in that process depend entirely on the "rest" of the driver stack that's interacting with that device.
ES_EVENT_TYPE_AUTH_IOKIT_OPEN (Endpoint Security) does not prevent using USB device if I send response ES_AUTH_RESULT_DENY for "AppleUSBHostDeviceUserClient"
First off, as a side note, I would recommend filing a bug specifically asking that ES_EVENT_TYPE_AUTH_IOKIT_OPEN include the io_object_t reference it's targeting, then posting the bug number back here. Looking over the requests we've had here, there are actually two different requests that we've received:
-
An API that would allow an ES client to intercept the driver load/matching process, preventing drivers from loading against a particular device/client/etc.
-
Asking for ES_EVENT_TYPE_AUTH_IOKIT_OPEN to include it's io_object_t target.
The problem here is that while #1 is (arguably) the more useful of the two options, it's also MUCH harder to implement and more dangerous to use. I haven't found a bug specifically focused on #2, which makes it harder to advocate for.
On the specific issue here...
...does not prevent using USB device if I send response ES_AUTH_RESULT_DENY for "AppleUSBHostDeviceUserClient"
...it all depends on what you're trying to block, however, I wouldn't expect this to block all that much. The issue here is that most "interesting" USB devices actually end up "bridging" into some other layer in the kernel, and that OTHER layer is where the actual "work" happens. SO, for example:
-
Mass storage devices go into SAM (SCSI Architecture Model)/IOStorage family, which then exists the kernel as BSD dev nodes.
-
HID devices (mice, keyboards, etc.) go into the HID driver stack.
etc...
One final note here is that, in general, blocking trying to "properly" block hardware is an inherently complicated task that requires a lot of knowledge about how the system and hardware works, as well as a great deal of experimentation and testing.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware