Dear Apple Developer Community,
I hope you're all doing well.
I'm running into an issue where a USB DEXT doesn’t seem to be fully registered in the IORegistry, which is preventing the user client (daemon) from connecting and communicating with it. The DEXT is supposed to authorize any USB device connections based on the daemon’s response.
Here’s a simplified example to illustrate the issue:
// MyUSBDEXT.h
class MyUSBDEXT : public IOService {
public:
virtual kern_return_t Start(IOService *provider) override;
virtual bool init() override;
virtual kern_return_t Stop(IOService *provider) override;
virtual kern_return_t NewUserClient(uint32_t type, IOUserClient **userClient) override;
};
// MyUSBDEXT.cpp
kern_return_t IMPL(MyUSBDEXT, Start) {
// USB device handling
kern_return_t result = RegisterService();
if (result != kIOReturnSuccess) {
os_log_error(OS_LOG_DEFAULT, "RegisterService() failed with error: %d", result);
goto Exit; // Exit if registration fails
}
// Wait for NewUserClient creation and daemon response
// Return: Allow or Deny the USB connection
}
kern_return_t IMPL(MyUSBDEXT, NewUserClient) {
// Handle new client creation
}
In the example above, IMPL(MyUSBDEXT, Start) waits for a user client to establish communication after calling RegisterService(), and only then does it proceed to allow or deny the USB device connection.
Based on my observations, even after RegisterService() returns kIOReturnSuccess, the DEXT entry appears in the IORegistry but remains unregistered, preventing user clients from connecting.
MyUSBDEXT <class IOUserService, id 0x100001185, !registered, !matched, active, busy 0, retain 7>
However, if IMPL(MyUSBDEXT, Start) does not wait after calling RegisterService(), the DEXT gets fully registered, allowing user clients to connect and communicate with it.
MyUSBDEXT <class IOUserService, id 0x100001185, registered, matched, active, busy 0, retain 7>
This creates a challenge: IMPL(MyUSBDEXT, Start) needs to wait for a user client to establish communication to Allow or Deny USB connections, but the user client can only connect after MyUSBDEXT::Start() completes.
According to Apple’s documentation, RegisterService() initiates the registration process for the service, but it is unclear when the process actually completes. https://developer.apple.com/documentation/kernel/ioservice/3180701-registerservice
Is there a way to ensure that RegisterService() fully completes and properly registers the entry in IORegistry before returning from IMPL(MyUSBDEXT, Start)?
Alternatively, in a USB DEXT, is it possible to make the USB device authorization decision (allow/deny) after IMPL(MyUSBDEXT, Start) has completed?
Or is there another recommended approach to handle this scenario?
Any insights would be greatly appreciated!
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
Dear Apple Developer Community,,
I understand that RPC is not the recommended IPC mechanism for communication between an Endpoint Security (ES) Extension or a Network System Extension and a daemon. However, I would like to clarify whether Apple currently allows the use of RPC (clnt_call()) as an IPC method for these extensions to communicate event details to a daemon.
Given that ES Extensions operate in a sandboxed environment, they may lack the necessary permissions to create network sockets (e.g., clnt_call() over TCP) on a properly signed macOS system with SIP enabled (macOS Sequoia).
Looking for clarification on the following points:
Whether RPC (clnt_call()) is currently supported as an IPC mechanism for ES Extensions or Network System Extensions?
If supported, does Apple have any plans to deprecate RPC-based IPC (such as clnt_call()) in the near future for these extensions?
I would appreciate any insights or references to official documentation on this topic.
Topic:
App & System Services
SubTopic:
Core OS