XPC is a a low-level (libSystem) interprocess communication mechanism that is based on serialized property lists.

Posts under XPC tag

54 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

XPC Resources
XPC is the preferred inter-process communication (IPC) mechanism on Apple platforms. XPC has three APIs: The high-level NSXPCConnection API, for Objective-C and Swift The low-level Swift API, introduced with macOS 14 The low-level C API, which, while callable from all languages, works best with C-based languages General: DevForums tag: XPC Creating XPC services documentation NSXPCConnection class documentation Low-level API documentation XPC has extensive man pages — For the low-level API, start with the xpc man page; this is the original source for the XPC C API documentation and still contains titbits that you can’t find elsewhere. Also read the xpcservice.plist man page, which documents the property list format used by XPC services. Daemons and Services Programming Guide archived documentation WWDC 2012 Session 241 Cocoa Interprocess Communication with XPC — This is no longer available from the Apple Developer website )-: Technote 2083 Daemons and Agents — It hasn’t been updated in… well… decades, but it’s still remarkably relevant. TN3113 Testing and Debugging XPC Code With an Anonymous Listener XPC and App-to-App Communication DevForums post Validating Signature Of XPC Process DevForums post Related tags include: Inter-process communication, for other IPC mechanisms Service Management, for installing and uninstalling Service Management login items, launchd agents, and launchd daemons Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com"
0
0
1.6k
Mar ’24
XPC Service not working in packaged app
I'm trying to use XPC communicate between a command line tool (launched from Terminal) and a macOS application. My code currently works when the app is launched from Xcode, but not if I launch the built app from the command line (open path-to-foo.app) or if I try and distribute the packaged application (via "Development" distribution). Notably, the XPC works if the command line tool is launched from the terminal as long as the app itself is launched from Xcode. I publish the XPC service using NSXPCListener(machServiceName: <team-identifier>.com.example.my-app.service) and connect to it using NSXPCConnection(machServiceName: machServiceName). Both my command line tool and my main app identical "app group" entitlements for $(TeamIdentifierPrefix)com.example.my-app and I verified the team identifier substitution was correct in both the app and command line tool after doing distributing for "App Store", exporting, unpacking the pkg and running codesign as described here: https://developer.apple.com/documentation/xcode/embedding-a-helper-tool-in-a-sandboxed-app
1
0
52
10m
Daemon in an app with a self-update feature
We've got a non-sandboxed app with a built-in daemon that does some root-privileged things for us on occasion. We're using the newest SMAppService APIs, using NSXPCConnections for communications, and generally things work as expected. The daemon is set up to terminate when the parent app terminates. Our app also has (and uses the daemon for) a self-update feature. Once the new app is downloaded, the daemon takes over, replaces the app in-place, terminates the old app and launches the new one. However, after this update, the daemon no longer works. Any other build & launch of the app will silently fail when trying to talk to the daemon. The XPC connection can be constructed as usual, no errors, the process goes along like it should app-side, but the daemon never actually launches and never responds. I can imagine there could be a few rules being broken here with the self-update and the built-in daemon, but what would they be and how can we work within the rules?
1
0
68
8h
NEMachServiceName failure to access after network extension upgrade
We have a product which uses a Network Extension (a socket filter and a packet content filter). The application contains the network extension, as well as an un-sandboxed LaunchDaemon which connects to the service at the NEMachServiceName. Occasionally, usually after an upgrade where the system extension is swapped for the new version, our un-sandboxed process isn't able to contact the network extension. From the logging, we receive the following XPC error (libxpc.dylib) [com.apple.xpc:connection] [0x7fd6d0307f40] failed to do a bootstrap look-up: xpc_error=[3: No such process] in the unsandboxed process. Eventually, we receive an invalidated callback on the XPC connection with the error Couldn’t communicate with a helper application.. We have confirmed that an appropriate service is running via the launchctl command, and the network extension process appears to have initialised correctly. We don't see any indication of a received connection at the Network Extension process however (probably not surprising given the error). Once a system enters this state, repeated attempts to connect are unsuccessful and continue to produce the same error. We've also confirmed that there are no XPC codec exceptions apparent that might cause the connection to fail. I'm at a bit of a loss to explain why this failure might be occurring, other than a problem in the bootstrap/launchd being able to find the appropriate service. Is there possibly some problem with unsandboxed processes accessing the sandboxed network extension via XPC? They are both provisioned in an app group together. Is there possibly some issue where attempting to connect at a critical point during network extension installation causes it to become inaccessible? We've observed this specifically on macOS 14.5 (23F79), however this is something we've noticed on other versions of macOS and our code. The problem isn't systematic, and systems end up in this state only occasionally. We do seem to find some customers have more instances of this problems than others, but we haven't been successful at teasing out any common thread that might explain why.
1
0
72
23h
GUI + XPC Service App Architecture Performance
Let's image that someone wants to use a background service to keep track of FSEvents activity, at the file level (a firehose, some might say). I choose this example, to indicate the volume and rate of data transmission in question. I'm not creating a front-end for FSEvents data, but my background service may generate data at a similar pace. The service runs off of user defined document/s that specify the FSEvent background filtering to be applied. Those that match get stored into a database. But filters can match on almost all the data being emitted by FSEvents. The user decides to check on the service's activity and database writes by launching a GUI that sends requests to the background service using XPC. So the GUI can request historic data from a database, but also get a real-time view of what FS events the service is busy filtering. So it's a client-server approach, that's concerned with monitoring an event stream over XPC. I understand XPC is a request/response mechanism, and I might look into using a reverse connection here, but my main concern is one of performance. Is XPC capable of coping with such a high volume of data transmision? Could it cope with 1000s of rows of table data updates per second sent to a GUI frontend? I know there are streaming protocol options that involve a TCP connection, but I really want to stay away from opening sockets.
7
0
176
1w
NSXPCConnection setCodeSigningRequirement: in sandbox works only with Developer ID signing
Hello, I use setCodeSigningRequirement: in sandboxed XPCService and it seems that no matter what I always get errSecCSNoSuchCode[1] when the app is signed with development certificate. The same application signed with DeveloperID is fine. I use following CSR for development signed builds. identifier com.example.app and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.1] exists and certificate leaf[field.1.2.840.113635.100.6.1.12] exists But also tried to simplify to identifier com.example.app or just true. If I validated the CSR with codesign -R I get "explicit requirement satisfied". I spotted this log line: Sandbox: com.example.app(67058) deny(1) file-read-data /Users/(...)/example-app/build/arm64-mac/src/mac/app/Debug/Example App.app/Contents/MacOS/ExampleApp So I disabled the sandbox for XPCService and now everything works. But then why the DeveloperID signed build works with XPCService sandboxed? ...or does it really? :) Just for completeness the CSR which I use in production build are: identifier com.example.app and anchor apple generic and certificate 1[field.1.2.840.113635.100.6.2.6] exists and certificate leaf[field.1.2.840.113635.100.6.1.13] exists and certificate leaf[subject.OU] = EXAMPLE
5
0
205
1w
Should embedded XPCServices validate incoming connections?
Hello, The man page for xpcservices.plist states that: Services embedded in an application bundle will only be visible to the containing application (...) What exactly "visible" means? Doest that mean that there is a mechanism to prevent other programs than the embedding application to access the XPCService's mach port or it just means that the XPCService is not listed (e.g. launchctl list) and if attacker can guess the mach port they can access it? I'm asking to understand if there is a security gain using the -[NSXPCConnection setCodeSigningRequirement:] for embedded XPCServices.
2
0
282
2w
sysext crashed while sending lots of log to host app
hi all. I subscribe the notify write event, every time I recieve a notify write event message i will send log data and reply block(didn't do nothing) with async method to host app(Objc XPC API).host app will reply immediately once it recieves data. after a while my sysext crashed, then I checked system log find the log below. launchd: exited with exit reason (namespace: 30 code: 0xc40000000004aaaa) - (unknown reason) is it because of exceeding the maximum limit of xpc's block queue length, or too many memory allocation, or... by the way, host app didn't crash. how this happened exactly? how could i solve it?
4
0
319
3w
How do you allow an XPC service to create a new file based on an NSURL that the user selected from an NSSavePanel?
How do you send an NSURL representing a new file, as returned from an NSSavePanel, to an XPC service such that the service is granted permission to create the file? I can successfully pass an NSURL to the XPC process if the NSURL represents an existing file. This is documented in Apple's Documentation: Share file access between processes with URL bookmarks This involves creating bookmark date while passing 0 in as the options. However, if you try to create bookmark data for an NSURL that represents a file that is not yet created, you do not get any bookmark data back and an error is returned instead: Error Domain=NSCocoaErrorDomain Code=260 "The file couldn’t be opened because it doesn’t exist." Simply passing the file path to the XPC process, by way of: xpc_dictionary_set_string(message, "file_path", url.fileSystemRepresentation); Does not grant the XPC create/write permissions. Is there an API or trick I'm missing? Note that the user should be allowed to save and create new files anywhere of their choosing, thus restricting URLs to only those within a group or container shared between the app and service isn't really viable. Using the latest of everything on macOS with the xpc_session API...
1
0
244
3w
FileHandle over XPC failure?
2024-06-04 15:17:59.618853+0100 ProxyAgent[20233:29237510] [xpc.exceptions] <NSXPCConnection: 0x60000331cb40> connection from pid 20227 on anonymousListener or serviceListener: Exception caught during decoding of received selector newFlowWithIdentifier:to:type:metadata:socket:, dropping incoming message. Exception: Exception while decoding argument 4 (#6 of invocation): <NSInvocation: 0x600001778780> return value: {v} void target: {@} 0x0 selector: {:} null argument 2: {@} 0x6000017787c0 argument 3: {@} 0x60000002d170 argument 4: {q} 1 argument 5: {@} 0x600001746600 argument 6: {@} 0x0 Exception: decodeObjectForKey: Object of class "NSFileHandle" returned nil from -initWithCoder: while being decoded for key <no key> The extension is in Swift; the recipient is in ObjC (wheeeeee). Based on the extension's logging, the FileHandle is not nil. I am trying to pass a FileHandle based on a socketpair up to the user-land code. The sockets are created happily. Any ideas what's going wrong here?
5
0
227
3w
XPC, Swift, ObjC, and arrays
I create a protocol that had, among other things: @objc func setList(_: [MyType], withReply: @escaping (Error?) -> Void) The daemon part is in Swift, while the calling part is in Objective-C. Because why not? (Actually, because the calling part has to deal with C++ code, so that's ObjC++; however, I wanted the stronger typing and runtime checking for the daemon part, so I wrote it in Swift.) The ObjC part uses NSArray<MyType*>. I set up an NSXPCConnection link, and create a (synchronous) proxy with the right protocol name. But when I try to do the XPC setList call, I get an error. I assume that's because it doesn't like the signature. (Surely this is logged somewhere? I couldn't find it, if so. 😩) But... if I have a signature of @objc func addItem(_: MyType, withReply: @escaping (Error?) -> Void), then it works. So I assume it's the array. (Oh, I've also tried it without the @objc; the protocol itself is defined as @objc.) I've tried changing to protocol signature to using NSArray, but same thing.
7
0
1.1k
Jun ’24
`listener failed to activate: xpc_error=[1: Operation not permitted]`
Hi :wave: I started a new project to experiment with EndpointSecurity framework. It seems to have been worked, but when I try to add XPC I face some troubles. I am not able to send XPC message from my app to my system extension. No runtime error, but when I'm inspecting logs: That correspond to this code: https://github.com/tony-go/TestES/blob/main/Extension/main.swift#L21-L30 Full project: https://github.com/tony-go/TestES/ I thought at first that it could come from a missing @objc somehere but it does not seems ... I also wonder why I cannot catch this error at runtime ?
12
0
381
Jun ’24
How to check XPCConnection is REALLY connected
I'm using XPC to do IPC with an agent service. I use NSXPCConnection initWithMachServiceName to create the connection and active it. Then I get the agent service remote object proxy with method remoteObjectProxyWithErrorHandler. But when the agent service unloaded, I can also get the remote proxy without any error. Is there anyway to check XPCConnection really connect to a XPC server?
1
0
249
May ’24
App sandbox extension revoked on Ventura
Hi everyone, first-time caller, long-ti... wait, no, I just got here. :) I am relatively new to all things Apple, so apologies in advance if it takes me a few goes to properly explain things. We have a framework, which includes an API, an XPC service, etc, and we have a device driver. We also have some sample apps that use the framework, and if they have the app sandbox capability, then we expect them to use the XPC Service instead of accessing our driver directly. This works fine on Monterey and presumably has worked fine on all previous versions of MacOS. Something seems to have changed on Ventura, and we don't understand what. When we build the same app on Ventura, it appears to be in the sandbox (according to the Sandbox column in Activity Monitor), but in the Console there is this line (twice): default <time> <OurAppName> Revoking sandbox extension; key = 0 Which we suspect is linked to the fact that the app then does not use the XPC Service, and instead accesses the driver directly, much to our surprise. Software built on developer's machines is "Automatically managed" and "Signed to Run Locally" in case that matters. Do we need to change our code to support Ventura and onward? Or is it a bizarre bug? Oh, I should say that I'm running the latest version of Ventura (13.6.7 as of writing) but not the latest Xcode (14.2 (14C18)) and CLI tools... can't remember how to find that version... Apple clang version 14.0.0 (clang-1400.0.29.202). Any help would be appreciated, thanks. Jeremy
6
0
378
May ’24
Launching agent installed with SMAppService
I am attempting to install and utilize an agent using the new(ish) SMAppService API with an existing app. The agent appears to install (no error is returned), but when I try to start the agent from Terminal, I get the following in the launchd.log: 2024-04-22 09:57:27.469039 (gui/502/com.redacted.service.agent) : internal event: WILL_SPAWN, code = 0 2024-04-22 09:57:27.469080 (gui/502/com.redacted.service.agent) : service state: spawn scheduled 2024-04-22 09:57:27.469081 (gui/502/com.redacted.service.agent) : service state: spawning 2024-04-22 09:57:27.469100 (gui/502/com.redacted.service.agent) : launching: one-shot 2024-04-22 09:57:27.469105 (gui/502/com.redacted.service.agent) : Allowing non-reentrant proxy for resolving path 2024-04-22 09:57:27.469947 (gui/502/com.redacted.service.agent [71866]) : xpcproxy spawned with pid 71866 2024-04-22 09:57:27.469960 (gui/502/com.redacted.service.agent [71866]) : internal event: SPAWNED, code = 0 2024-04-22 09:57:27.469964 (gui/502/com.redacted.service.agent [71866]) : service state: xpcproxy 2024-04-22 09:57:27.469997 (gui/502/com.redacted.service.agent [71866]) : internal event: SOURCE_ATTACH, code = 0 2024-04-22 09:57:27.506283 (gui/502/com.redacted.service.agent [71866]) : Service could not initialize: posix_spawn(/Users/chrisf/Library/Developer/Xcode/DerivedData/Redacted-gttupgdyakodzddurpavhmscwabs/Build/Products/Debug/Redacted App.app/Contents/MacOS/Service Agent.app), error 0xd - Permission denied 2024-04-22 09:57:27.506306 (gui/502/com.redacted.service.agent [71866]) : initialization failure: 23E224: xpcproxy + 31420 [1098][A7EF179C-FBCC-349E-A7D2-09B2F1408413]: 0xd 2024-04-22 09:57:27.506309 (gui/502/com.redacted.service.agent [71866]) : internal event: INIT, code = 13 2024-04-22 09:57:27.506313 (gui/502/com.redacted.service.agent [71866]) : job state = spawn failed 2024-04-22 09:57:27.507148 (gui/502/com.redacted.service.agent [71866]) : xpcproxy exited due to exit(78) 2024-04-22 09:57:27.507153 (gui/502/com.redacted.service.agent [71866]) : exited due to exit(78) 2024-04-22 09:57:27.507162 (gui/502/com.redacted.service.agent [71866]) : already handled failed init, ignoring 2024-04-22 09:57:27.507170 (gui/502/com.redacted.service.agent [71866]) : service state: exited 2024-04-22 09:57:27.507186 (gui/502/com.redacted.service.agent [71866]) : internal event: EXITED, code = 0 (tldr: error 0xd - Permission denied) I'd also be curious how we are expected to launch agents once registered with SMAppService. Is it sufficient simply to make an XPC call to an exposed method? Thanks!
1
0
316
Apr ’24
Error 159 - Sandbox restriction when connecting to XPC service
Hello Apple Developer Community, I'm encountering an issue with my macOS application where I'm receiving the following error message: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.FxPlugTestXPC was invalidated: failed at lookup with error 159 - Sandbox restriction." UserInfo={NSDebugDescription=The connection to service named com.FxPlugTestXPC was invalidated: failed at lookup with error 159 - Sandbox restriction.} This error occurs when my application tries to establish a connection to an XPC service named com.FxPlugTestXPC. It appears to be related to a sandbox restriction, but I'm unsure how to resolve it. I've checked the sandboxing entitlements and ensured that the necessary permissions are in place. However, the issue persists. Has anyone encountered a similar error before? If so, could you please provide guidance on how to troubleshoot and resolve this issue? Any help or insights would be greatly appreciated. Thank you. this is some photos about my entitlements :
16
0
1.3k
Apr ’24
Callback is not invoked when a closure callback-style call is executed in XPC
I noticed a problem while writing a program using XPC on macOS. When I write it in the form of a closure that receives the result of an XPC call, I can't receive it forever. I add an XPC target in Xcode, the sample code is used in the pass closure format, but can't I use closure passing with XPC? My Environment: Xcode 15.3 macOS 14.4.1 caller (closure version) struct ContentView: View { @State var callbackResult: String = "Waiting…" var body: some View { Form { Section("Run XPC Call with no argument and no return value using callback") { Button("Run…") { callbackResult = "Running…" let service = NSXPCConnection(serviceName: "net.mtgto.example-nsxpc-throws-error.ExampleXpc") service.remoteObjectInterface = NSXPCInterface(with: ExampleXpcProtocol.self) service.activate() guard let proxy = service.remoteObjectProxy as? any ExampleXpcProtocol else { return } defer { service.invalidate() } proxy.performCallback { callbackResult = "Done" } } Text(callbackResult) ... } } } callee (closure version) @objc protocol ExampleXpcProtocol { func performCallback(with reply: @escaping () -> Void) } class ExampleXpc: NSObject, ExampleXpcProtocol { @objc func performCallback(with reply: @escaping () -> Void) { reply() } } I found this problem can be solved by receiving asynchronous using Swift Concurrency. caller (async version) struct ContentView: View { @State var callbackResult: String = "Waiting…" var body: some View { Form { Section("Run XPC Call with no argument and no return value using callback") { Button("Run…") { simpleAsyncResult = "Running…" Task { let service = NSXPCConnection(serviceName: "net.mtgto.example-nsxpc-throws-error.ExampleXpc") service.remoteObjectInterface = NSXPCInterface(with: ExampleXpcProtocol.self) service.activate() guard let proxy = service.remoteObjectProxy as? any ExampleXpcProtocol else { return } defer { service.invalidate() } await proxy.performNothingAsync() simpleAsyncResult = "DONE" } Text(simpleAsyncResult) ... } } } callee (async version) @objc protocol ExampleXpcProtocol { func performNothingAsync() async } class ExampleXpc: NSObject, ExampleXpcProtocol { @objc func performNothingAsync() async {} } To simplify matters, I write source code that omits the arguments and return value, but it is not also invoked by using callback style. All sample codes are available in https://github.com/mtgto/example-nsxpc-throws-error
2
0
379
Apr ’24
XPC Service Connection Invalidated Immediately on Launch
Development Environment: Xcode Version: 14.3.1 macOS Ventura Version: 13.6.2 Architecture: Intel I am developing a macOS app with an accompanying XPC service and am encountering an issue where the XPC connection is immediately invalidated upon trying to establish it. The error message received is: Error Domain=NSCocoaErrorDomain Code=4099 "The connection to service named com.appname.macos.app-name-xpc was invalidated." UserInfo={NSDebugDescription=The connection to service named com.appname.macos.app-name-xpc was invalidated: failed at lookup with error 3 - No such process.} Here's what I have verified so far: The XPC service has the correct CFBundleIdentifier and is located within the Contents/XPCServices directory of my app's bundle. Info.plist for the XPC service has ServiceType set to Bundled. The XPC service target's Installation Directory is the default location for XPC services (@executable_path/../XPCServices). Code signing and entitlements have been verified for both the main app and the XPC service, and disabling the sandbox doesn't resolve the issue. The main app and XPC service are part of the same App Group, and both have the App Sandbox capability enabled. Here's a snippet of the Swift code that establishes the XPC connection: let xpcConnection = NSXPCConnection(serviceName: "com.appname.macos.app-name-xpc") xpcConnection.remoteObjectInterface = NSXPCInterface(with: ServiceProtocol.self) xpcConnection.resume() And here's the ServiceProtocol for reference: @objc public protocol ServiceProtocol: NSObjectProtocol { @objc func executeUnixExecutable(arguments: [String], completionHandler: @escaping (ResultType) -> Void) func interruptUnixExecutable() func closeUnixExecutablePipes() } When I run the app, the connection is invalidated without any further details as to why. I'm not sure if I'm missing a configuration step or if there's an issue with my XPC service setup. Has anyone experienced this issue or have suggestions on what else I can check to resolve this?
2
0
1.7k
Apr ’24
Are XPCSession and XPCListener incomplete(ly documented)?
I've been experimenting with the new low-level Swift API for XPC (XPCSession and XPCListener). The ability to send and receive Codable messages is an appealing alternative to making an @objc protocol in order to use NSXPCConnection from Swift — I can easily create an enum type whose cases map onto the protocol's methods. But our current XPC code validates the incoming connection using techniques similar to those described in Quinn's "Apple Recommended" response to the "Validating Signature Of XPC Process" thread. I haven't been able to determine how to do this with XPCListener; neither the documentation nor the Swift interface have yielded any insight. The Creating XPC Services article suggests using Xcode's XPC Service template, which contains this code: let listener = try XPCListener(service: serviceName) { request in request.accept { message in performCalculation(with: message) } } The apparent intent is to inspect the incoming request and decide whether to accept it or reject it, but there aren't any properties on IncomingSessionRequest that would allow the service to make that decision. Ideally, there would be a way to evaluate a code signing requirement, or at least obtain the audit token of the requesting process. (I did notice that a function xpc_listener_set_peer_code_signing_requirement was added in macOS 14.4, but it takes an xpc_listener_t argument and I can't tell whether XPCListener is bridged to that type.) Am I missing something obvious, or is there a gap in the functionality of XPCListener and IncomingSessionRequest?
2
0
381
Apr ’24