UserSendCDB fails due to permissions

I created a custom class that inherits from IOUserSCSIPeripheralDeviceType00 in the DriverKit SCSIPeripheralsDriverKit framework. When I attempted to send a vendor-specific command to a USB storage device using the UserSendCDB function of this class instance, the function returned the error:

kIOReturnNotPrivileged  (iokit_common_err(0x2c1))  // privilege violation

However, when using UserSendCDB in the same way to issue standard SCSI commands such as INQUIRY or Test Unit Ready, no error occurred and the returned sense data was valid.

Why is UserSendCDB able to send standard SCSI commands successfully, but vendor-specific commands return kIOReturnNotPrivileged? Is there any required entitlement, DriverKit capability, or implementation detail needed to allow vendor-specific CDBs?

Below are the entitlements of my DriverKit extension:

<dict>
    <key>com.apple.developer.driverkit.transport.usb</key>
    <array>
        <dict>
            <key>idVendor</key>
            <integer>[number of vendorid]</integer>
        </dict>
    </array>
    <key>com.apple.developer.driverkit</key>
    <true/>
    <key>com.apple.developer.driverkit.allow-any-userclient-access</key>
    <true/>
    <key>com.apple.developer.driverkit.allow-third-party-userclients</key>
    <true/>
    <key>com.apple.developer.driverkit.communicates-with-drivers</key>
    <true/>
    <key>com.apple.developer.driverkit.family.scsicontroller</key>
    <true/>
</dict>

If there is any additional configuration or requirement to enable vendor-specific SCSI commands, I would appreciate your guidance.

Environment: macOS15.6 M2 MacBook Pro

However, when using UserSendCDB in the same way to issue standard SCSI commands such as INQUIRY or Test Unit Ready, no error occurred and the returned sense data was valid.

You're allowed to send some commands (basically, anything that's inherently non-disruptive) at any time.

Why is UserSendCDB able to send standard SCSI commands successfully, but vendor-specific commands return kIOReturnNotPrivileged? Is there any required entitlement, DriverKit capability, or implementation detail needed to allow vendor-specific CDBs?

Did you call UserSuspendServices() first? That's required to send vendor specific commands?

Below are the entitlements of my DriverKit extension:

Just to make sure this is clear and because entitlements tend to be blamed for lots of issues, no, this is not an entitlement issue.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Kevin, thank you for your reply.

Did you call UserSuspendServices() first? That's required to send vendor specific commands?

Calling UserSuspendServices() allowed commands to be sent, but it required unmounting storage to execute the command.

I want to store the application on the storage and send vendor-specific commands. Is there a way to send commands without unmounting the storage?

Calling UserSuspendServices() allowed commands to be sent, but it required unmounting storage to execute the command.

Yes. In my previous message, I said:

"You're allowed to send some commands (basically, anything that's inherently non-disruptive) at any time."

The reason this behavior exists is to prevent DEXT from sending disruptive commands to mounted devices.

I want to store the application on the storage and send vendor-specific commands.

I'm not sure what you mean here. Your DEXT is going to be copied and installed onto the local system, so I'm not sure this is really an achievable goal.

Is there a way to send commands without unmounting the storage?

No.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

UserSendCDB fails due to permissions
 
 
Q