I built an app which hosts a CMIOExtension. The app works, and it can activate the extension. The extension loads in e.g. Photo Booth and shows the expected video (a white horizontal line which moves down the picture).
I have a couple of questions about this though.
The sample Camera Extension is built with a CMIOExtension dictionary with just one entry, CMIOExtensionMachServiceName which is $(TeamIdentifierPrefix)$(PRODUCT_BUNDLE_IDENTIFIER)
This Mach service name won't work though. When attempting to activate the extension, sysextd says that the extensions has an invalid mach service name or is not signed, the value must be prefixed with one of the App Groups in the entitlement.
So in order to get the sample extension to activate from my app, I have to change its CMIOExtensionMachServiceName to
<my team ID>.com.mycompany.my-app-group.<myextensionname>
Is this to be expected?
The template CMIOExtension generates its own video using a timer. My app is intended to capture video from a source, filter that video, then feed it to the CMIOExtension, somehow. The template creates an app group called "$(TeamIdentifierPrefix)com.example.app-group", which suggests that it might be possible to use XPC to send frames from the app to the extension.
However, I've been unable to do so. I've used
NSXPCConnection * connection = [[NSXPCConnection alloc] initWithMachServiceName:, using the CMIOExtensionMachServiceName with no options and with the NSXPCConnectionPrivileged option. I've tried NSXPCConnection * connection = [[NSXPCConnection alloc] initWithServiceName: using the extension's bundle identifier. In all cases when I send the first message I get an error in the remote object proxy's handler:
Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named <whatever name I try> was invalidated: failed at lookup with error 3 - No such process."
According to the "Daemons and Services Programming Guide" an XPC service should have a CFBundlePackageType of XPC!, but a CMIOExtension is of type SYSX. It can't be both.
Does the CMIOExtension loading apparatus cook up a synthetic name for the XPC service, and if so, what is it? If none, how is one expected to get pixel buffers into the camera extension?
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
The device I am trying to develop a firmware updater for is an NVMe drive with a USB4 interface. It can connect in USB4 mode (tunneled NVMe), in USB 3 mode or in USB 2 mode.
In USB 2 and USB 3 mode, the device descriptor shows one interface with two alternates. Alternate 0 uses the bulk-only protocol, with one IN and one OUT pipe. Alternate 1 uses the UAS protocol, with two IN and two OUT pipes.
I use identical code in my driver to send custom CDBs. I can see using IORegistryExplorer that in USB 2 mode, macOS chooses alternate 0, the bulk-only protocol. My custom CDBs and their accompanying data pay loads are put on the bus, more or less as expected.
In USB 3 mode, macOS chooses alternate 1, the UAS protocol. My custom CDB is put on the bus, but no payload data is transferred.
Is this expected behavior?
If so, is there a way to force the OS to choose alternate 0 even when on USB 3, perhaps with another dext?
I'll file a bug about this when Feedback Assistant lets me.
I'm trying to help out one of our vendors by building a skeleton PCI dext which they can flesh out.
However, I can't seem to get the signing right.
I can't sign it at all using no team or my personal team. "Signing for requires a development team", and "Personal development teams ... do not support the System Extension capability".
I can't sign the driver because "DriverKit Team Provisioning Profile: doesn't match the entitlements file's value for the com.apple.developer.driverkit.transport.pci entitlement.
I think this problem occurs because our company has already been assigned a transport.pci entitlement, but for our own PCI vendor ID. But I want to build and test software that works with our vendor's PCI device.
I tried generating a profile for the driver manually, it contained only our own company's PCI driver match:
IOPCIPrimaryMatch = "0x0000MMMM&0x0000FFFF";
where MMMM is our own PCI vendor ID.
Is there a better way to inspect the profile Xcode is using than the postage-stamped sized info popup which truncates the information? I would download the generated profile but it doesn't appear on the profile, but Xcode is accessing it from somewhere.
When I look at the available capabilities I can add to an app identifier on the Developer portal, I see com.apple.developer.driverkit.transport.usb, which is "development only". There's no "development only" capability for PCI. Does this mean it isn't possible to develop even a proof-of-concept PCI driver without being first granted the DriverKit PCI (Primary Match) entitlement?
When adding capabilities to a driver, the list of available capabilities shown in Xcode has one "DriverKit PCI (Primary Match) entry", but if I double click it, two such entries appear in the Signing and Capabilities tab for my driver target. On the Developer portal, when I look at my driver's Identifier, there are two Capabilities labelled DriverKit PCI (Primary Match). Why?
I've been given an Xcode project which produces a command line tool which links to a dylib. I have the dylib, but not its source code.
I change the signing option for the command line tool target so it is signed automatically by my personal team.
On an attempt to run the tool, it fails to load the dylib, because the dylib is signed with a different certificate. I manually codesign the dylib with the same certificate I am using for the command line app.
Now, I can build the app, but not run it. If I try to do so, I see four dialogs telling me “libXXX.dylib” can’t be opened because Apple cannot check it for malicious software, then the console tells me "'/path/to/libXXX.dylib' not valid for use in process: library load disallowed by system policy)"
I found an old document about Gatekeeper (https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html) which suggests that Gatekeeper just won't let me do this - I can't just put the dylib next to the executable, although the dynamic linker finds the dylib, Gatekeeper doesn't like it because the dylib isn't inside the app bundle (there is none), and isn't in one of the well-known places.
I dealt with this by making a do-nothing app which I can sign with my personal certificate. Then I replace the signature on the dylib (and its dependent dylibs) with my own. I add the command line tool and all its dylib dependencies to the do-nothing app, then add those files into the Copy Bundle Resources phase of the do-nothing app.
Now, the command line tool and its dylibs all live in do-nothing.app/Contents/Resources, and I can run the tool from there without Gatekeeper complaining.
Is there an easier way (aside from asking my supplier for static libraries)? And if this is the only way, is Contents/Resources the right place to put command line tools and the dylibs they link to?
I am having similar problems to this guy on Stack Overflow over a year ago:
https://stackoverflow.com/questions/77627852/functions-of-iouserscsiperipheraldevicetype00-class-in-scsiperipheralsdriverkit
There are also a few questions on this forum about this object, none of which have answers.
I can get my driver to match and instantiate, but
nobody calls my UserDetermineDeviceCharacteristics (which does nothing, just returns kIOReturnSuccess)
I can attempt to call UserSuspendServices(), UserResumeServices() or UserReportMediumBlockSize() and all of them return kIOReturnUnsupported. It doesn't matter if I've unmounted the disk or not.
Is the custom driver supposed to be instantiated beside the kernel's IOSCSIPeripheralDeviceType00, or should it replace it?
What should its IOProviderClass be?
What should its IOClass be - IOUserService, or something else?
see FB19678139 and FB19677920
I'm trying to build the DriverKit template driver target in an Xcode project which contains an app targeting iPadOS 17. I've made no modifications to the DriverKit template.
When building, I get this link error
ld: file cannot be open()ed, errno=2 path=/Applications/Xcode 15.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.profile_driverkit.a in '/Applications/Xcode 15.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/lib/darwin/libclang_rt.profile_driverkit.a'
anyone know how to fix this? My search turned up something about building llvm from sources, which seems like overkill to put a DriverKit driver into an iPad app.
I recently built an update to one of our apps, which installs a driver extension.
The new version won't launch on my Mac, Finder says it "can't be opened".
I captured the logs, which say "no matching profile found":
error 2024-01-10 14:36:03.306061 -0800 taskgated-helper <app-bundle-id>: Unsatisfied entitlements: com.apple.developer.system-extension.install, com.apple.developer.team-identifier
info 2024-01-10 14:36:03.306279 -0800 amfid Requirements for restricted entitlements failed to validate, error -67671, requirements: '<private>'
error 2024-01-10 14:36:03.306287 -0800 amfid Restricted entitlements not validated, bailing out. Error: Error Domain=AppleMobileFileIntegrityError Code=-413 "No matching profile found" UserInfo={NSURL=<private>, unsatisfiedEntitlements=<private>, NSLocalizedDescription=No matching profile found}
default 2024-01-10 14:36:03.306432 -0800 amfid /Applications/<app-bundle-id>/Contents/MacOS/<app-name> not valid: Error Domain=AppleMobileFileIntegrityError Code=-413 "No matching profile found" UserInfo={NSURL=file:///Applications/C<escaped-app-name>/, unsatisfiedEntitlements=<CFArray 0x14f3041d0 [0x1dd7d39a0]>{type = immutable, count = 2, values = (
0 : <CFString 0x14f3055a0 [0x1dd7d39a0]>{contents = "com.apple.developer.system-extension.install"}
1 : <CFString 0x14f304130 [0x1dd7d39a0]>{contents = "com.apple.developer.team-identifier"}
)}, NSLocalizedDescription=No matching profile found}
default 2024-01-10 14:36:03.306514 -0800 kernel AMFI: bailing out because of restricted entitlements.
default 2024-01-10 14:36:03.306523 -0800 kernel mac_vnode_check_signature: /Applications/<app-bundle-id>/Contents/MacOS/<app-name>: code signature validation failed fatally: When validating /Applications/<app-bundle-id>/Contents/MacOS/<app-name>:
Code has restricted entitlements, but the validation of its code signature failed.
Unsatisfied Entitlements: com.apple.developer.system-extension.installcom.apple.developer.team-identifier
The thing is, when I run this command
codesign -v -vvv <path-to-app>
the app is valid on disk and satisfies its Designated Requirement
and these two commands:
codesign --display --entitlements - security cms -D -i <path-to-app>/Contents/embedded.provisionprofile
when run against the old app (which works) and the new app (which doesn't) have absolutely identical outputs. The certificates haven't expired yet.
Where else should we be looking to figure out where we've messed up? We know we changed the signing and notarization flow; the working build was made by a person using Xcode, the new app was built, signed and notarized using the command line tools (xcodebuild and notarytool).
I have a macOS app which contains a dext. I'd like to distribute it to external testers using TestFlight, so it has to pass Mac App Store review. It failed, because the App Sandbox entitlement was missing.
I checked the app, it has the entitlement, but the dext does not. However, the .entitlements file used by the dext does contain App Sandbox set to true.
I tried adding a "fake-entitlement" value to the .entitlements file, and that made it into the dext's code signature, but the App Sandbox entitlement appears to be stripped out by the build process?
For a dext target, it isn't possible to add the App Sandbox capability in Xcode's Signing and Capability section. I have to add the entitlement manually in the .entitlement file (or it was put there by the Xcode driver template, I don't remember).
I've tried clean building several times, I've tried Xcode 15.0.1, 15.2 and 15.3, but the result is always the same. I'm inspecting the entitlements using
codesign -dvvv --entitlements -
Does anyone know what I can do to put the App Sandbox entitlement into my dext's signature? Is this happening to anyone else?
I am working on a Swift package which uses CoreAudio, and includes some tests in a testTarget which use the Testing framework, and a couple of executableTarget targets which exercise the same code. I'm using Xcode 16.2 on macOS 15.3.1.
One of the things I do in the test code is create a HAL plugin, then find that plugin using the kAudioHardwarePropertyTranslateUIDToDevice.
Finding the plugin that I just created always fails from within a Swift Testing test, unless I run the test which creates the plugin individually first, then separately, run the test which finds the plugin, by clicking on the little arrows next to the function names.
If I put the tests in a serialized suite (so creation always happens first, then finding), running the suite always fails - it creates the plugin, but can't find it. If I run the 'find my plugin' test again manually, it is always found.
If I call the same functions from a regular executable (the thing created by a "executableTarget" in my .package.swift file), the just-created plugin is always found.
Is there a way to mimic the runtime environment of a regular executable in a Swift Testing target, or am I misunderstanding something?
this my be related to this issue: https://github.com/swiftlang/swift/issues/76882 but I don't understand it well enough to be sure.
I have a non-shipping internal test app which is macOS only. It uses AppKit and .xib files to describe the UI.
On Sonoma, the app renders with most of its UI quite blurry, as if a 10 pixel Gaussian blur were applied to it. The blur is applied to entire views, not just the text. It doesn't vary with screen resolution. I observed this behavior with one of the Sonoma betas but I think it went away when I re-launched the app - at any rate, I forgot about it.
I've updated my dev machine to the shipping Sonoma and the problem is extant. I opened up the .xib file in Xcode and the blurriness is visible there too. I haven't applied any effect layers to my UI.
Not all of the views in my UI are blurry.
Has anyone else seen this?
I have an Xcode project (generated from Qt) which is signed by a post-processing script.
It uses the invocation:
codesign -o runtime --sign "$(CODE_SIGN_IDENTITY)"
CODE_SIGN_IDENTITY is set to "Apple Development" in the Build Settings for the target.
The signing step fails with this complaint
Apple Development: ambiguous (matches "Apple Development: <my name> (an ID)" and "Apple Development: <my company email> (another ID)" in login.keychain-db)
It is true, I do have two Apple Development certificates. I thought one is for personal development (when you pick the personal team) and the other for company development (when I pick the company team).
I have other Xcode projects (built "by hand") which have CODE_SIGN_IDENTITY set to "Apple Development" and with Automatic signing turned on, and they build just fine, even though I have two certificates with common names beginning "Apple Development".
However, when I look at the build log of those regular Xcode projects, which are signed by Xcode rather than in a post-processing script, the Signing step logs this:
Signing Identity: Apple Development: (an ID)
not simply "Apple Development". Xcode seems to have resolved the ambiguity all on its own before calling codesign. It then calls codesign using the hash of the certificate as its identifier.
How can I emulate Xcode's behavior here? The postprocessing script runs on different developer's machines - they all have multiple "Apple Development" certificates, and they are all different from one another.
I've made a dext and a user client that overrides IOUserSCSIPeripheralDeviceType00, with the object of writing device firmware to the driver. I can gain and relinquish exclusive access to the device, I can call UserReportMediumBlockSize and get back a sensible answer (512).
I can build command parameters with the INQUIRY macro from IOUserSCSIPeripheralDeviceHelper.h and send that command successfully using UserSendCB, and I receive sensible-looking Inquiry data from the device.
However, what I really want to do is send a WriteBuffer command (opcode 0x3B), and that doesn't work. I have yet to put a bus analyzer on it, but I don't think the command goes out on the bus - there's no valid sense data, and the error returned is 0xe00002bc, or kIOReturnError, which isn't helpful.
This is the code I have which doesn't work.
kern_return_t driver::writeChunk(const char * buf, size_t atOffset, size_t length, bool lastOne)
{
DebugMsg("writeChunk %p at %ld for %ld", buf, atOffset, length);
SCSIType00OutParameters outParameters;
SCSIType00InParameters response;
memset(&outParameters, 0, sizeof(outParameters));
memset(&response, 0, sizeof(response));
SetCommandCDB(&outParameters.fCommandDescriptorBlock,
0x3B, // byte 0, opcode WriteBuffer command
lastOne ? 0x0E : 0x0F, // byte 1 mode: E=save deferred, F = download and defer save
0, // byte 2 bufferID
(atOffset >> 16), // byte 3
(atOffset >> 8), // byte 4
atOffset, // byte 5
(length >> 16), // byte 6
(length >> 8), // byte 7
length, // byte 8
0, // control, byte 9
0, 0, 0, 0, 0, 0); // bytes 10..15
outParameters.fLogicalUnitNumber = 0;
outParameters.fBufferDirection = kIOMemoryDirectionOut;
outParameters.fDataTransferDirection = kSCSIDataTransfer_FromInitiatorToTarget;
outParameters.fTimeoutDuration = 1000; // milliseconds
outParameters.fRequestedByteCountOfTransfer = length;
outParameters.fDataBufferAddr = reinterpret_cast<uint64_t>(buf);
uint8_t senseBuffer[255] = {0};
outParameters.fSenseBufferAddr = reinterpret_cast<uint64_t>(senseBuffer);
outParameters.fSenseLengthRequested = sizeof(senseBuffer);
kern_return_t retVal = UserSendCDB(outParameters, &response);
return retVal;
}
I've watched the video of WWDC 2019 session 702, System Extensions and DriverKit, and I'm still a little puzzled.For instance, what's the point of USBDriverKit, that is, why would I use it in preference to the already extant user-mode USB APIs? The demo shows an extension that does nothing - it logs to the debugger, but it doesn't provide any services to multiple clients in the system. In a KEXT, those services are provided by publishing them in the IORegistry; they provide well-known interfaces in the kernel to which a well-known user client can connect. If my extension ships in my own app, and provides services only to that app, I may as well implement the extension's functions directly in my app.How does my app (or more importantly, a third-party app) communicate with my dext? That wasn't covered in session 702. Neither was the case of replacing or augmenting an existing system driver, for example filtering the data passing through a USB mass storage driver, based on sideband data which the standard system driver cannot convey. For a kext, I would simply call IORegisterService and the rest of the stack would be build on top of my driver.Is the sample code for the demo of session 702 available? Any other sample code for DriverKit?
I added a Camera Extension to my app, using the template in Xcode 13.3.1. codesign tells me that the app and its embedded system extension are correctly signed, their entitlements seem to be okay. But when I submit an activation request for the extension, it returns with this failure:
error: Error Domain=OSSystemExtensionErrorDomain Code=9 "(null)"
localized failure reason: (null)
localizedDescription: The operation couldn’t be completed. (OSSystemExtensionErrorDomain error 9.)
localizedRecoverySuggestion: (null)
What could be the reason? code 9 appears to mean a "validation error", but how do I figure out what is invalid?
My goal is to implement a moving background in a virtual camera, implemented as a Camera Extension, on macOS 13 and later. The moving background is available to the extension as a H.264 file in its bundle.
I thought i could create an AVAsset from the movie's URL, make an AVPlayerItem from the asset, attach an AVQueuePlayer to the item, then attach an AVPlayerLooper to the queue player.
I make an AVPlayerVideoOutput and add it to each of the looper's items, and set a delegate on the video output.
This works in a normal app, which I use as a convenient environment to debug my extension code. In my camera video rendering loop, I check self.videoOutput.hasNewPixelBuffer , it returns true at regular intervals, I can fetch video frames with the video output's copyPixelBuffer and composite those frames with the camera frames.
However, it doesn't work in an extension - hasNewPixelBuffer is never true. The looping player returns 'failed', with an error which simply says "the operation could not be completed". I've tried simplifying things by removing the AVPlayerLooper and using an AVPlayer instead of an AVQueuePlayer, so the movie would only play once through. But still, I never get any frames in the extension.
Could this be a sandbox thing, because an AVPlayer usually renders to a user interface, and camera extensions don't have UIs?
My fallback solution is to use an AVAssetImageGenerator which I attempt to drive by firing off a Task for each frame each time I want to render one, I ask for another frame to keep the pipeline full. Unfortunately the Tasks don't finish in the same order they are started so I have to build frame-reordering logic into the frame buffer (something which a player would fix for me). I'm also not sure whether the AVAssetImageGenerator is taking advantage of any hardware acceleration, and it seems inefficient because each Task is for one frame only, and cannot maintain any state from previous frames.
Perhaps there's a much simpler way to do this and I'm just missing it? Anyone?