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

Posts under XPC tag

74 Posts

Post

Replies

Boosts

Views

Activity

What is the alternative to Environment and Library Constraints before macOS 14.0?
In the macOS 14.0 SDK, environment and library constraints were introduced, which made defense against common attack vectors relatively simple (especially with the LightWeightCodeRequirements framework added in 14.4). Now, the application I'm working on must support macOS 13.0 too, so I was looking into alternatives that do work for those operating systems as well. What I found myself is that the SecCode/SecStaticCode APIs in the Security Framework do offer very similar fashion checks as the LightWeightCodeRequirements framework does: SecCodeCopySigningInformation can return values like signing identifier, team identifier, code requirement string and so on. SecStaticCodeCreateWithPath can return a SecStaticCode object to an executable/app bundle on the file system. Let's say, I would want to protect myself against launchd executable swap. From macOS 14.0 onward, I would use a Spawn Constraint for this, directly in the launchd.plist file. Before macOS 14.0, I would create a SecStaticCode object for the executable path found in the launchd.plist, and then examine its SecCodeCopySigningInformation dictionary. If the expectations are met, only then would I execute the launchd.plist-defined executable or connect to it via XPC. Are these two equivalent? If not, what are the differences?
3
0
763
Jan ’25
Check whether XPC remote proxy responds to selector, without causing exception and connection invalidation?
I have several processes maintaining NSXPConnection to an XPC service. The connections are bi-directional. Each side service and clients) of the connection exports an object, and an XPCInterface. The @protocols are different - to the service, and from the service to clients. So long as all the "clients" fully implement their "call-back" @protocol, there's no problem. All works fine. However - If a client does NOT implement a method in the "call back protocol", or completely neglects to export an object, or interface - and the service attempts to call back using the nonexistent method -- the XPC connection invalidates immediately. So far - expected behaviour. However, if I want the service to behave to the client a little like a "delegate" style -- and check first whether the client "respondsToSelector" or even - supports an interface BEFORE calling it, then this doesn't work. When my XPC service tries the following on a client connection: if (xpcConnection.remoteObjectInterface == nil) os_log_error(myXPCLog, "client has no remote interface); the condition is never met - i.e. the "remoteObjectInterface is never nil even when the client does NOT configure its NSXPCConnection with any incoming NSXPCInterface, and does not set an "exportedObject" Furthermore, the next check: if ([proxy respondsToSelector:@selector(downloadFiltersForCustomer:withReply:)]) { } will not only fail - but will drop the connection. The client side gets the invalidation with the following error: <NSXPCConnection: 0x600000b20000> connection to service with pid 2477 named com.proofpoint.ecd: received an undecodable message for proxy 1 (no exported object to receive message). Dropping message. I guess the "undecidable message" is the respondsToSelector - because the code doesn't get to attempt anything else afterwards, the connection drops. Is there a way to do this check "quietly", or suffering only "interruption", but without losing the connection,
3
0
716
Jan ’25
OSSystemExtensionRequestDelegate doesn't get a callback; XPC connection cancelled
I'm attempting to install a NetworkExtension as a system extension, using the OSSystemExtensionManager.shared.submitRequest(request) API call. I can see from console logs and systemextensionsctl that my system extension is getting installed, but the OSSystemExtensionRequestDelegate I attach to the request never gets a callback. In the console logs I see: com.apple.sx default 14:13:25.811827+0400 sysextd activateDecision found entry to replace: com.coder.Coder-Desktop.VPN, BundleVersion(CFBundleShortVersionString: "1.0", CFBundleVersion: "1") default 14:13:25.811888+0400 sysextd initial activation decision: requestAppReplaceAction(<sysextd.Extension: 0xa94030100>) com.apple.sx default 14:13:25.811928+0400 sysextd notifying client of activation conflict com.apple.xpc default 14:13:25.812156+0400 Coder Desktop [0x154f2d5b0] invalidated because the current process cancelled the connection by calling xpc_connection_cancel() com.apple.xpc default 14:13:25.813924+0400 sysextd [0xa941d4280] invalidated because the client process (pid 2599) either cancelled the connection or exited com.apple.sx default 14:13:25.814027+0400 sysextd client connection (pid 2599) invalidated It appears that something within my app process is cancelling the XPC connection to sysextd, but I'm certainly not calling it from within my code. Presumably something within the OSSystemExtension* APIs are cancelling the connection but I don't know why. It seems to be happening very quickly (within a few hundred ms) after sending the request, and before sysextd can reply. What could cause this connection to be canceled?
8
0
627
Jan ’25
XPC between main app and system extension
Hello, I'm developing a Mac application that uses a network extension. I'm trying to implement XPC to pass data between my main app and system extension and I'm using the SimpleFirewall demo app as a guide to do this. One thing I can't understand is how the ViewController in the SimpleFirewall main app has access to the class IPCConnection in the SimpleFirewallExtension without it being public and without SimpleFirewallExtension being imported in ViewController.
1
0
540
Jan ’25
crash At iOS18.0+ BSXPCCnx:com.apple.backboard.hid-services.xpc (BSCnx:client:BKHIDEventDeliveryObserver)
hello everyone On iOS18.0+, app crashed at BSXPCCnx:com.apple.backboard.hid-services.xpc (BSCnx:client:BKHIDEventDeliveryObserver) when app enter background sometimes crash stacktrace: Crashed: BSXPCCnx:com.apple.backboard.hid-services.xpc (BSCnx:client:BKHIDEventDeliveryObserver) 0 libsystem_pthread.dylib 0x4078 pthread_mutex_lock + 12 1 ilink_live 0xbd884 (缺少 UUID 973fe6c5058c35bda98679b0c8aa0129) 2 ilink_live 0xb75fc (缺少 UUID 973fe6c5058c35bda98679b0c8aa0129) 3 libsystem_c.dylib 0x23190 __cxa_finalize_ranges + 492 4 libsystem_c.dylib 0x22f8c exit + 32 5 BackBoardServices 0x31b78 -[BKSHIDEventObserver init] + 98 6 BoardServices 0x1dc78 __31-[BSServiceConnection activate]_block_invoke.182 + 128 7 BoardServices 0x1beb4 __61-[BSXPCServiceConnectionEventHandler _connectionInvalidated:]_block_invoke + 196 8 BoardServices 0x4a58 BSXPCServiceConnectionExecuteCallOut + 240 9 BoardServices 0x1d6e8 -[BSXPCServiceConnectionEventHandler _connectionInvalidated:] + 180 10 libdispatch.dylib 0x2248 _dispatch_call_block_and_release + 32 11 libdispatch.dylib 0x3fa8 _dispatch_client_callout + 20 12 libdispatch.dylib 0xb5cc _dispatch_lane_serial_drain + 768 13 libdispatch.dylib 0xc158 _dispatch_lane_invoke + 432 14 libdispatch.dylib 0xb42c _dispatch_lane_serial_drain + 352 15 libdispatch.dylib 0xc158 _dispatch_lane_invoke + 432 16 libdispatch.dylib 0x1738c _dispatch_root_queue_drain_deferred_wlh + 288 17 libdispatch.dylib 0x16bd8 _dispatch_workloop_worker_thread + 540 18 libsystem_pthread.dylib 0x3680 _pthread_wqthread + 288 19 libsystem_pthread.dylib 0x1474 start_wqthread + 8 when crash happened ,most of time app recieved CBManagerStateResetting and CBManagerStateUnsupported event i would appreciate any insights or recommendations on how to resolve this issue thx crash_stacktrace.txt
1
1
641
Jan ’25
Operation not permitted on xpc_listener_create
Hi, I'm trying to create a launch daemon that uses XPC to receive requests from an unprivileged app. Ultimately both components will be written in Go. For now I'm trying to write a PoC in Objective-C to make sure I get everything right, so I'm compiling / signing from the CLI, and writing plist files by hand -- I'm not using XCode. My current daemon code is pretty much the same as the boilerplate code that XCode generates when creating a new 'XPC Service': #import <stdio.h> #include <xpc/xpc.h> int main(int argc, char *argv[]) { xpc_rich_error_t error; dispatch_queue_t queue = dispatch_queue_create("com.foobar.daemon", DISPATCH_QUEUE_SERIAL); xpc_listener_t listener = xpc_listener_create( "com.foobar.daemon", queue, XPC_LISTENER_CREATE_NONE, ^(xpc_session_t _Nonnull peer) { xpc_session_set_incoming_message_handler(peer, ^(xpc_object_t _Nonnull message) { int64_t firstNumber = xpc_dictionary_get_int64(message, "firstNumber"); int64_t secondNumber = xpc_dictionary_get_int64(message, "secondNumber"); // Create a reply and send it back to the client. xpc_object_t reply = xpc_dictionary_create_reply(message); xpc_dictionary_set_int64(reply, "result", firstNumber + secondNumber); xpc_rich_error_t replyError = xpc_session_send_message(peer, reply); if (replyError) { printf("Reply failed, error: %s", xpc_rich_error_copy_description(replyError)); } }); }, &error); if (error != NULL) { printf("ERROR: %s\n", xpc_rich_error_copy_description(error)); exit(1); } printf("Created listener: %s", xpc_listener_copy_description(listener)); // Resuming the serviceListener starts this service. This method does not return. dispatch_main(); return 0; } I'm compiling, signing and installing my daemon with the following commands: build_foobar() { clang -Wall -x objective-c -o com.foobar.daemon poc/main.m codesign --force --verify --verbose --options=runtime \ --identifier="com.foobar.daemon" \ --sign="Mac Developer: Albin Kerouanton (XYZ)" \ --entitlements=poc/entitlements.plist \ com.foobar.daemon } install_foobar() { sudo cp com.foobar.daemon /Library/PrivilegedHelperTools/com.foobar.daemon sudo cp poc/com.foobar.daemon.plist /Library/LaunchDaemons/com.foobar.daemon.plist sudo launchctl bootout system/com.foobar.daemon || true sudo launchctl bootstrap system /Library/LaunchDaemons/com.foobar.daemon.plist } Here's the content of my entitlements.plist file: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.application-identifier</key> <string>ABCD.com.foobar.daemon</string> </dict> </plist> And finally, here's my launchd plist file: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.foobar.daemon</string> <key>Program</key> <string>/Library/PrivilegedHelperTools/com.foobar.daemon</string> <key>ProgramArguments</key> <array> <string>/Library/PrivilegedHelperTools/com.foobar.daemon</string> </array> <key>RunAtLoad</key> <false/> <key>StandardOutPath</key> <string>/tmp/com.foobar.daemon.out.log</string> <key>StandardErrorPath</key> <string>/tmp/com.foobar.daemon.err.log</string> <key>Debug</key> <true/> </dict> </plist> Whenever I start my service using sudo launchctl start com.foobar.daemon, it exits with the following error message: ERROR: Unable to activate listener: failed at listener activation with error 1 - Operation not permitted System logs don't show anything interesting -- they're just repeating the same error message. I tried to add / remove some properties from both the entitlement and the launchd plist file but to no avail. Any idea what's going wrong?
1
0
563
Jan ’25
best practices for communication between system extension and daemon
Hello, My team has developed a DNS proxy for macOS. We have this set up with a system extension that interacts with the OS, and an always-running daemon that does all the heavy lifting. Communication between the two is DNS request and response packet traffic. With this architecture what are best practices for how the system extension communicates with a daemon? We tried making the daemon a socket server, but the system extension could not connect to it. We tried using XPC but it did not work and we could not understand the errors that were returned. So what is the best way to do this sort of thing?
3
0
724
Jan ’25
Crash:Exceeded system-wide per-process Port Limit
Hi everyone, I’m encountering a crash in my app and need help understanding what’s causing it and how to resolve it. As stated in the crash report, the issue is caused by exceeding the system-wide per-process port limit. Can you tell me how to locate and identify why this is happening? Below are the full report of the crash log: crash.log Summary of Crash: ------------------------------------- Translated Report (Full Report Below) ------------------------------------- Incident Identifier: B509FF2B-C8D8-4E9F-B664-E24464CFD5F8 CrashReporter Key: b390cfe931a83efde49bd8b523023a275b55ef64 Hardware Model: iPhone14,2 Process: MyApp [22515] Path: /private/var/containers/Bundle/Application/F73212A7-4CB9-485A-A8B7-8114F4E9A9AB/MyApp.app/MyApp Identifier: com.beeasy.app.id.enterprise Version: 3.41.38-ID-MySDKMemory-12261114 (3.41.38-ID-MySDKMemory-12261114) Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd [1] Coalition: com.beeasy.app.id.enterprise [515] Date/Time: 2024-12-29 01:29:48.3023 +0800 Launch Time: 2024-12-26 16:38:36.7895 +0800 OS Version: iPhone OS 16.6.1 (20G81) Release Type: User Baseband Version: 2.80.01 Report Version: 104 Exception Type: EXC_RESOURCE (SIGKILL) Exception Codes: 0x000000000001c1d6, 0x0000000000000000 Termination Reason: PORT_SPACE 14123288431433990614 (Limit 115158 ports) Exceeded system-wide per-process Port Limit Triggered by Thread: 64 Thread 64 name: AURemoteIO::IOThread Thread 64 Crashed: 0 libsystem_kernel.dylib 0x20ce5eca4 mach_msg2_trap + 8 1 libsystem_kernel.dylib 0x20ce71b74 mach_msg2_internal + 80 2 libsystem_kernel.dylib 0x20ce71e4c mach_msg_overwrite + 540 3 libsystem_kernel.dylib 0x20ce5f1e8 mach_msg + 24 4 libEmbeddedSystemAUs.dylib 0x238bb2148 void* caulk::thread_proxy<std::__1::tuple<caulk::thread::attributes, AURemoteIO::IOThread::IOThread(AURemoteIO&, caulk::thread::attributes const&, caulk::mach::os_workgroup_managed const&)::'lambda'(), std::__1::tuple<>>>(void*) + 556 5 libsystem_pthread.dylib 0x22dcda6b8 _pthread_start + 148 6 libsystem_pthread.dylib 0x22dcd9b88 thread_start + 8
3
0
702
Jan ’25
How to get the full process name like Activity Monitor
I'm try to monitor all processes by ES client. But I found the process name is different from the Activity Monitor displayed. As shown in the picture below, there are ShareSheetUI(Pages) and ShareSheetUI(Finder) processes in Activity Monitor, but I can only get the same name ShareSheetUI, I thought of many ways to display the name in parentheses, but nothing worked, so there is a way to display the process name like Activity Monitor?
1
0
452
Jan ’25
iOS18 crash at BSXPCCnx:com.apple.backboard.hid-services.xpc
when app enter background,sometimes crash at BSXPCCnx:com.apple.backboard.hid-services.xpc (BSCnx:client:BKHIDEventDeliveryManager) this is crash stack: 0 libsystem_pthread.dylib 0x3b30 pthread_mutex_lock + 12 1 ilink_live 0xbd884 (缺少 UUID 973fe6c5058c35bda98679b0c8aa0129) 2 ilink_live 0xb75fc (缺少 UUID 973fe6c5058c35bda98679b0c8aa0129) 3 libsystem_c.dylib 0x23d68 __cxa_finalize_ranges + 492 4 libsystem_c.dylib 0x23b64 exit + 32 5 BackBoardServices 0x579ec -[BKSHIDEventDeliveryManager _initForTestingWithService:] + 98 6 BoardServices 0xbae8 __31-[BSServiceConnection activate]_block_invoke.182 + 128 7 BoardServices 0x17620 __61-[BSXPCServiceConnectionEventHandler _connectionInvalidated:]_block_invoke + 196 8 BoardServices 0x8f64 BSXPCServiceConnectionExecuteCallOut + 240 9 BoardServices 0x18e5c -[BSXPCServiceConnectionEventHandler _connectionInvalidated:] + 180 10 libdispatch.dylib 0x2370 _dispatch_call_block_and_release + 32 11 libdispatch.dylib 0x40d0 _dispatch_client_callout + 20 12 libdispatch.dylib 0xb6d8 _dispatch_lane_serial_drain + 744 13 libdispatch.dylib 0xc214 _dispatch_lane_invoke + 432 14 libdispatch.dylib 0x17258 _dispatch_root_queue_drain_deferred_wlh + 288 15 libdispatch.dylib 0x16aa4 _dispatch_workloop_worker_thread + 540 16 libsystem_pthread.dylib 0x4c7c _pthread_wqthread + 288 17 libsystem_pthread.dylib 0x1488 start_wqthread + 8 when crash happened ,most of time app recieved CBManagerStateResetting and CBManagerStateUnsupported event
1
0
582
Dec ’24
Is there anyway to deny user copy file content
I'm developing a file access control system. In order to protect the file content copied out, I'm finding a way to deny user copy file content to other files. I know there are data transmission between the copied application and pboard service by XPC. But I don't know how to interrupt the data transmission. Or I can do something to stop the copied data send to the Clipboard. So is there any way to prevent the contents of a file being copied?
0
0
498
Dec ’24
responseHandler of sendProviderMessage of NETunnelProviderSession is being called implicitly/prematurely
Hi, For one our requirement sendProviderMessage is been used to send some event/message from app to system extension, In my requirement, responseHandler in system extension would get explicitly called approximately after 1 min due to some async download file task. But observing some strange behavior that responseHandler is getting called implicitly after ~20-30 seconds even before the code hit the place where its called explicitly. And that is the only place I'm calling responseHandler. Can somebody please help about this strange behavior, Is there any implicit timeout interval associated with the responseHandler. Thanks &amp;amp; Regards, Preethi
1
0
465
Dec ’24
Running Sensitive Code in a Separate Process for iOS XCFramework
Hello everyone, We have an iOS XCFramework that we distribute to our clients, and we're exploring ways to enhance its security. Specifically, we’d like to isolate the most sensitive code by running it in a separate process, making it harder to tamper with. During our research, we considered using XPC for iOS but found its functionality to be quite limited. We also explored App Extensions, but unfortunately, they cannot be integrated into an XCFramework. This leads us to the question: Is it possible to spawn a new process to run in parallel with the main one in iOS? If so, could you provide guidance or suggest alternative approaches to achieve this within the constraints of iOS development? Thank you in advance for your insights and advice! Best regards, Stoyan
1
3
460
Dec ’24