简体   繁体   中英

USB peripherals arbitration on macOS

The DiskArbitration framework on macOS provides a simple way to intercept volumes mounts and authorise it or not using DARegisterDiskMountApprovalCallback .

I'm looking for something similar for all the other USB devices like HID devices, network interfaces and in general every USB peripheral.

I'm moving in the direction of IOKit : Introduction to USB Device Interface Guide and I can see how to communicate with a USB device but I can't find anything similar to an arbitration mechanism.

Any idea? Kernel extension isn't an option.


macOS 11 update

With macOS a new AUTH event called ES_EVENT_TYPE_AUTH_IOKIT_OPEN has been introduced. The event is called correctly but digging in the object headers I fund:

/**
 * @brief Open a connection to an I/O Kit IOService
 *
 * @field user_client_type A constant specifying the type of connection to be
 *        created, interpreted only by the IOService's family.
 *        This field corresponds to the type argument to IOServiceOpen().
 * @field user_client_class Meta class name of the user client instance.
 *
 * This event is fired when a process calls IOServiceOpen() in order to open
 * a communications channel with an I/O Kit driver.  The event does not
 * correspond to driver <-> device communication and is neither providing
 * visibility nor access control into devices being attached.
 */
typedef struct {
    uint32_t user_client_type;
    es_string_token_t user_client_class;
    uint8_t reserved[64];
} es_event_iokit_open_t;

:(

This screws my plans:

The event does not correspond to driver <-> device communication and is neither providing visibility nor access control into devices being attached.

Any idea on how to get the device info in another way?

Since macOS 10.15, you can use the EndpointSecurity API to authorise IOKit user clients, ie get a callback whenever a user process attempts to IOServiceOpen() .

The relevant event for this is ES_EVENT_TYPE_NOTIFY_IOKIT_OPEN / es_event_iokit_open_t .

I don't believe this applies in any way to in-kernel clients, for those you'd need to go down the kext route.

Prior to 10.15, a kext was the only option in general - the MAC framework kernel API has a similar policy callback to the new EndpointSecurity one.

Not a complete answer, but it looks like there is a way to subscribe to device notifications with IOKit.

Apple has provided ionotifyCB.c here: https://opensource.apple.com/source/IOKitUser/IOKitUser-502/ionotifyCB.c.auto.html

It doesn't build for me as-is, but I was able to make it work with some minor patching:

@@ -23,5 +23,6 @@
 /*
-cc ionotifyCB.c -o /tmp/ion -Wall -Wno-four-char-constants -framework IOKit -undefined warning
+cc ionotifyCB.c -o /tmp/ion -Wall -Wno-four-char-constants -framework IOKit -framework CoreFoundation
 */
 
+#include <stdio.h>
 #include <ctype.h>
@@ -35,2 +36,3 @@
 #include <CoreFoundation/CFRunLoop.h>
+#include <IOKit/graphics/IOGraphicsLib.h>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM