Post not yet marked as solved
So I'm having issues communicating with a endpoint security system extension via XPC. Both the application and the extension are signed, notarized, and members of the same group ID. I've confirmed that the extension is running with systemextensionsctl list and launchctl list. I've also confirmed that the xpc end is available with launchctl procinfo <extension_pid>. The mach service name is correct according to this post - https://developer.apple.com/forums/thread/118211?answerId=366391022#366391022 (TEAMID.bundleID.xpc). I also use the NSXPCConnection NSXPCConnection.Options.privileged
option when creating the connection. When I use connection.remoteObjectProxyWithErrorHandler
, I received an error "Couldn't communicate with a helper application". This error message is very vague and does not help me further troubleshoot. Are there any other logs that I should be looking at in the console app?
Post not yet marked as solved
Hi all,
I am having a mysterious problem trying to load a user LaunchAgent under Big Sur - It is the .plist of gniemetz's automount.sh https://github.com/gniemetz/automount
for mounting SMB shares via pwd access from the Keychain -
Placed the .sh into /usr/local/bin, chmod 644 and chown user:staff
Placed the LaunchAgent .plist into ~/Library/LaunchAgents (created LaunchAgents it as it didn't exist), same chmod/chown.
drwxr-xr-x&#9;&#9;3&#9; users&#9;&#9; 96 Nov&#9;1 22:13 LaunchAgents
~/Library/LaunchAgentsrw-r--r--&#9;&#9;1&#9; users&#9; 1038 Nov&#9;1 22:13 it.niemetz.automount.plist
/usr/local
drwxr-xr-x&#9;&#9;4 root&#9;&#9;wheel&#9;&#9;128 Nov&#9;1 21:52 bin
/usr/local/binrwxr-xr-x&#9;&#9;1 root&#9;&#9;wheel&#9;30310 Oct 29 21:58 automount.sh
then the following:
Load failed: 5: Input/output error
For the life of me, I cannot find anywhere what this means...
launchctl start ~/Library/LaunchAgents/it.niemetz.automount.plist
completes with no errors, syntax also parses OK
/Users//Library/LaunchAgents/it.niemetz.automount.plist: OK
I have added Terminal and /bin/bash to Full Disk Access under Security...
Launching the script manually as /usr/local/bin/automount.sh works fine.
Console shows
system.log shows this when load -w is run:
00:27:14 mac-mini-Big-Sur com.apple.xpc.launchd[1] (com.apple.xpc.launchd.user.domain.1000002.100006.Aqua): entering bootstrap mode
Nov&#9;3 00:27:14 mac-mini-Big-Sur com.apple.xpc.launchd[1] (com.apple.xpc.launchd.user.domain.1000002.100006.Aqua): exiting bootstrap mode
For easy reference the .plist is pasted at the end -
Anyone seen this error before?
Thanks!
++
Label
it.niemetz.automount
LimitLoadToSessionType
Aqua
RunAtLoad
WatchPaths
/etc/resolv.conf
/Library/Preferences/SystemConfiguration/NetworkInterfaces.plist
/Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist
ProgramArguments
/usr/local/bin/automount.sh
--mountall
Hi all,
According to the reference link,
Packaging a Daemon with a Provisioning Profile - https://developer.apple.com/forums/thread/129596
I changed our launchd daemon to run as an .app.
When generating a Provisioning Profile, I added our Development computer (including UUID) into 'Devices'.
But when I ran .app/Contents/MacOS/FamRTServicebig on our macOS Big Sur test environment, this error occurred:
embedded provisioning profile not valid: file:///Library/Application%20Support/test/bin/FamRTServicebig.app/Contents/embedded.provisionprofile
error: Error Domain=CPProfileManager Code=-212 "Provisioning profile does not allow this device." UserInfo={NSLocalizedDescription=Provisioning profile does not allow this device.}
Questions:
Could you let me know how to resolve this error?
Is it necessary to install the Provisioning profile in the test device as well?
Thanks in advance for your help.
Post not yet marked as solved
I'm trying to send an IOSurfaceRef across an NSXPCConnection on osx 10.13 and I'm having trouble with the solution that was provided in the forum thread "Efficiently sending data from an XPC process to the host application." https://developer.apple.com/forums/thread/126716 From that thread:
> However, that specific problem got resolved on 10.12 where we introduced a new Objective-C
IOSurface
object, and that object is transportable directly over
NSXPCConnection
. So double yay!
But it doesn’t seem to work. I have a very simple service protocol that includes
(void)sendFrame:(IOSurfaceRef)frame;
along with some basic NSString sending methods that successfully transfer across my NSXPCConnection. I have a valid (non-NULL) IOSurface in my app that I send to my helper app with sendFrame, and when the call is executed in the helper, the resulting frame is always NULL.
On the other hand, I’ve also tried creating an IOSurface with the (deprecated) kIOSurfaceIsGlobal property and sending the IOSurface’s ID instead with:
(void)sendFrameID:(uint32_t)frameID;
and
[_service sendFrameID:IOSurfaceGetID(surface)];
And on the helper app side, I look up the IO to get an IOSurfaceRef:
IOSurfaceRef frame = IOSurfaceLookup(frameID);
and it works correctly – I get a valid IOSurface which I can display and see the same pixel contents in both the app and the helper.
So what is meant by the new IOSurface object in 10.12 is “transportable directly” over NSXPCConnection? How is it supposed to work? I’m specifically interested in no-copy transfer. Thanks!
Post not yet marked as solved
I’ve got an application, which uses (a couple of) XPC service(s) to accomplish various tasks. Since recently, I don’t know when exactly but probably after some macOS update, I started seeing these messages coming out when XPC services are used:
[connection] nw_endpoint_handler_set_adaptive_read_handler [C1.1 140.82.121.6:443 ready socket-flow (satisfied (Path is satisfied), viable, interface: en1, ipv4, dns)] unregister notification for read_timeout failed
or
[connection] nw_endpoint_handler_set_adaptive_write_handler [C1.1 140.82.121.6:443 ready socket-flow (satisfied (Path is satisfied), viable, interface: en1, ipv4, dns)] unregister notification for write_timeout failed
This happens when the service want’s to use outgoing connection. Not that it only happens in Xcode during debugging, but the deployment version of the application/XPC emits these messages to the console as well. However, everything works correctly as it has before. I’d like to surpass those messages going into the console, but I’d also like to understand what they actually mean and why they appear in the first place. Searching the Internet didn’t really revealed any useful info, so I hope someone here can help me. Anyone else seeing those?
Post marked as Apple Recommended
Quinn, you've often suggested that to validate the other side of an XPC connection, we should use the audit token. But that's not available from the XPC object, whereas the PID is. So everyone uses the PID.
While looking for something completely unrelated, I found this in the SecCode.h file
OSStatus SecCodeCreateWithXPCMessage(xpc_object_t message, SecCSFlags flags,
SecCodeRef * __nonnull CF_RETURNS_RETAINED target);
Would this be the preferred way to do this now? At least from 11.0 and up.
Like I said, I was looking for something completely unrelated and found this and don't have the cycles right now to try it. But it looks promising from the description and I wanted to check in with you about it in case you can say yes or no before I get a chance to test it.
Thanks
Post not yet marked as solved
Hello -
TLDR - Is there any sample code to demonstrate how one goes about creating dedicated XPCServices to wrap ARM and Intel-specific dylibs?
We have an app we're looking at moving to a universal binary.
In that same app we have a framework that currently wraps R functionality by directly linking to /Library/Frameworks/R.framework/Current .
R now has dedicated Intel and ARM builds (https://mac.r-project.org/)
After watching the 2020 WWDC session "Port your Mac app to Apple silicon" (https://developer.apple.com/videos/play/wwdc2020/10214/?time=2006), it sounds like, for us to deploy a universal binary I should look at wrapping the R interaction bits into dedicated ARM and Intel XPC services so the appropriate architecture for R will run.
Is anyone aware of any sample code or extended documentation demonstrating the ins and outs of how to think about this?
Thank you
Post not yet marked as solved
This is a follow up to feedback FB9144718, which we also discussed at a WWDC21 "Performance, power, and stability" lab session.
Issue Summary
The actual issue we are facing is that our XPC service is not running as fast as we would expect it to be, especially not on Intel machines; somewhat better on M1 machines but still not really good.
After a lot of profilling with instruments, it finally turned out that the problem is caused by our processing getting regularly stopped as our processing thread is being preempted and put on hold for sometimes a tramendous amount of time (up to over 32 ms have been monitored). Even it is preempted for just a couple of ms most of the time, this is still a lot considering that the actual work it would otherwise perform is only in the range of microseconds.
The reason why this is happening is probably caused by the fact that we don't use the XPC service just for processing application messages through the XPC protocol, which we do as well, but also retrieve requests through a mach port from another process.
This causes our thread priority to be dropped down to 4 (see highlighted log line) and that's the reason why we get preempted for so long. The reason why it's not equally dramatic on M1 is that we are not preempted there, instead we are forced to run on the high efficiency cores instead of the high performance ones.
Ideas from the Lab
Other than completely restructuring our entire implementation which is eventually going to happen in the future anyway for Big Sur and newer, we still have to maintain this structure as long as we need to also support pre-Big Sur macOS version, so it would be great to have a less dramatic fix.
Two suggestions were made at the lab:
Change the RunLoopType in the XPC Plist from dispatch_main to NSRunLoop. We tried that but that didn't made any difference.
Add a key ProcessType with the value Interactive to the XPC Plist. This key is not documented for XPC services, only for launchd daemons but we were told it should actually work for XPC services as well. We tried that as well, both, top level as well as adding it to the XPC sub-key but that didn't make a difference either.
Another Idea That Didn't Work
Now that second suggestion made me look up that key in the man page for launchd.plist and what I found there was pretty interesting. Apparently there is a ProcessType value documented as
Adaptive
Adaptive jobs move between the Background and Interactive classifications based on activity over XPC connections. See xpc_transaction_begin(3) for details.
This seems to be our problem. Our XPC service is considered inactive when it processes messages over the mach port. Looking up the documentation of xpc_transaction_begin(3) tells me:
Services may extend the default behavior using xpc_transaction_begin() and xpc_transaction_end(), which increment and decrement the transaction count respectively. This may be necessary for services that send periodic messages to their clients, not in direct reply to a received message.
Using these two messages also frees us from the requirement to enable/disable sudden termination our own as it will automatically be controlled by these two functions as well. Yet even using these two functions to indicate activity doesn't prevent us from being preempted at regular intervals as our priority still drops to priority level 4 while we are still in the middle of processing (haven't called xpc_transaction_end() yet) . We seem to use it correctly though as it correctly disables sudden termination on our behalf as long as our XPC service remain in the active state (it will only receive mach messages for processing while in that state) and also gets re-enabled when we leave the active state again.
Final Thoughts
Also on the man page of xpc_transaction_begin() is written:
The XPC runtime will also automatically manage the service's priority based on where a message came from. If an app sends a message to the service, the act of sending that message will boost the destination service's priority and resource limits so that it can more quickly fill the request. If, however, a service gets a message from a background process, the service stays at a lower priority so as not to interfere with work initiated as a direct result of user interaction.
It looks like this is not working the way we use the XPC service at the moment. Our mach port messages either come from a System Extension (Big Sur and up) or from a root daemon started by launchd (Catalina and below, ProcessType is Interactive and nice value is -10) but apparently these messages cannot boost our XPC service and so it will stay on low prio.
Hi I am trying to implement XPC between my helper app and my network extension. It is giving me this error when I try to get the remoteObjectProxyWithErrorHandler
Error Domain=NSCocoaErrorDomain Code=4097 "connection to service on pid 0 named 9A48B11J6J.com.myapp.app.Extension" UserInfo={NSDebugDescription=connection to service on pid 0 named 9A48B11J6J.com.myapp.app.Extension}
Why could this be happening?
Post not yet marked as solved
I am creating a Safari Web Extension that uses an app extension to communicate with another macOS app.
The idea is to allow the safari web extension in the browser to communicate with an external app back and forth
To achieve this, I am using an XPC service as a launch agent and I have the following entitlement in the sandbox:
com.apple.security.temporary-exception.mach-lookup.global-name
This communication works and I would like to know if this will be accepted by the App Store.
If not, what modifications would I need to make here? Are there alternative communication methods as I definitely need to talk to this external app?
Hello,
I've tried following this thread: https://developer.apple.com/forums/thread/134013 for getting my network extension to communicate via XPC with the daemon, but I keep getting this error:
from Console.app
Sandbox: "App name"(57277) deny(1) mach-lookup "bundle id"
I can see that the daemon is running and when I try setting up the listener for it, it doesn't actually call the delegate function, func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) which causes the connection in the network extension as well the host app to not be able to actually communicate with the daemon.
Any ideas on how to fix it? Thanks
Post not yet marked as solved
Hi!
I'm looking for some insight and guidance on using the Foundation.Process type with a PTY (Psuedo Terminal) so that the subprocess can accept input and behave as if it was running via a terminal.
The reason for needing a PTY is that for programs like ssh or in my case (xcodes) which ask for user input including passwords, running these via Foundation.Process does not display the prompts to the user as the output is usually buffered (this works fine in the Xcode debugger console but when running via a real terminal that is buffered the prompts are never displayed in the terminal)
Looking at other threads it seems like correct approach here is create a PTY and use the filehandles to attach to the Process.
While I've got this to work to the point where prompts are now shown, I cant seem to figure out how to pass input back to the process as these are being controlled by the PTY.
Here is my Process setup:
let process = Process()
// Setup the process with path, args, etc...
// Setup the PTY handles
var parentDescriptor: Int32 = 0
var childDescriptor: Int32 = 0
guard Darwin.openpty(&parentDescriptor, &childDescriptor, nil, nil, nil) != -1 else {
fatalError("Failed to spawn PTY")
}
parentHandle = FileHandle(fileDescriptor: parentDescriptor, closeOnDealloc: true)
childHandle = FileHandle(fileDescriptor: childDescriptor, closeOnDealloc: true)
process.standardInput = childHandle
process.standardOutput = childHandle
process.standardError = childHandle
With this setup I then read the parent handle and output any result it gets (such as the input prompts):
parentHandle?.readabilityHandler = { handle in
guard let line = String(data: handle.availableData, encoding: .utf8), !line.isEmpty else {
return
}
logger.notice("\(line)")
}
When process.run() is executed the program runs and I can see it asks for Apple ID: input in my terminal, however, when typing input into the terminal the process does not seem to react to this input.
I've tried forwarding the FileHandle.standardInput:
FileHandle.standardInput.readabilityHandler = { handle in
parentHandle?.write(handle.availableData)
}
But this doesn't seem to work either.
What is the recommended way to setup a PTY with Foundation.Process for executing arbitrary programs and having them behave as if they were being run in a terminal context?
Most of the resources I found online are about other languages and I'd like to stick with Foundation.Process vs. doing anything custom in C/C++ if possible as it just makes it easier to reason about / maintain. The resources for Swift on this topic are very lacking and I've checked out some open source projects that claim to do this but most require manually sending input to the PTY handle vs. accepting them from the user in a terminal.
Any insight / help is very much appreciated!
Post not yet marked as solved
I tried low level XPC API. Here is the sample code.
int
main(int argc, char *argv[])
{
init_dispatch_queue();
xpc_main(handler);
es_client_t *client;
es_new_client_result_t result = es_new_client(&client, ^(es_client_t *c, const es_message_t *msg) {
handle_event(c, msg);
});
if (result != ES_NEW_CLIENT_RESULT_SUCCESS) { os_log_error(OS_LOG_DEFAULT, "Failed to create the ES client: %d", result);
return 1;
}
es_event_type_t events[] = { ES_EVENT_TYPE_AUTH_EXEC, ES_EVENT_TYPE_AUTH_OPEN };
if (es_subscribe(client, events, sizeof(events) / sizeof(events[0])) != ES_RETURN_SUCCESS) {
es_delete_client(client);
return 1;
}
dispatch_main();
}
xpc_main() function internally calls dispatch_main. Other extension code didn't execute. I added XPCService dict in info.plist and added RunLoopType as NSRunLoop as given in link. But it still don't work well.
NSXPConnection API that allows extension to function. I can't use these API as pyobjc do not support block calls.
Can we make low level xpc_main() to execute in second thread and not block extension.
Post not yet marked as solved
Is there a reliable way to know that an application was started using launchd, and not on command-line or from Finder?
Post not yet marked as solved
At present, we can create an NSXPC listener in a launch agent process which a sandboxed app extension can communicate with via the com.apple.security.temporary-exception.mach-lookup.global-name entitlement.
If I were to pass an NSXPCListener endpoint to this XPC service can the app extension act as a listener for incoming connections from the launch agent process? Will the sandbox impose restrictions on this?
Post not yet marked as solved
We see warnings like this logged by our processes using XPC:
(Foundation) [com.apple.runtime-issues:Foundation] *** -[NSXPCDecoder validateAllowedClass:forKey:]: NSSecureCoding allowed classes list contains [NSObject class], which bypasses security by allowing any Objective-C class to be implicitly decoded. Consider reducing the scope of allowed classes during decoding by listing only the classes you expect to decode, or a more specific base class than NSObject. This will become an error in the future. Allowed class list: {(
"'NSObject' (0x7ff844ee0d88) [/usr/lib]"
)}
As far as we can see, there is no explicit NSObject in allowed classes for any XPC connection. Where does this list and NSObject come from?
Post not yet marked as solved
I'm adding an embedded XPC service to a Safari Extension to handle some user sensitive data. I've been reading anything I can get my hands on, and I know that since the service is private, no other process besides my extension should be able to connect to it. That's great.
However, I want to be sure that the channel is safe from man in the middle attacks. Digging in, the output of sudo launchctl procinfo <pid> has among other things, an address to a Unix socket under SSH_AUTH_SOCK. I'm wondering if Unix file sockets are the underlying technology used to deliver these XPC messages, are the payloads encrypted, and if those messages can be intercepted.
I'm using the NSXPXConnection API, rather than the lower-level XPC API, if that makes a difference.
Post not yet marked as solved
Hi folks,
I'm trying to build communication between the main app and its helper via inter-process communication.
I found here that it is possible if the apps are in the same app group. But I really cannot make it work, and cannot understand what I do wrong. It works all good if I add com.apple.security.temporary-exception.mach-lookup.global-name entitlement, so the setup seems to be correct? Where should I look to fix it? Also because having that entitlement means that it is gonna be tricky to get through the App Review.
Post not yet marked as solved
Folks,
I've a bare bone XPC Service, built with Xcode 12.x.
I can get it work under Xcode interactive debugger. But from command line I get the Illegal instruction.
A similar project with XPC client don't see the problem.
Any help ?
Eventually it would be part of launchctl based daemon
TIA
-P
Post not yet marked as solved
I have a CoreMediaIO based DAL plugin written in Swift which currently poll a website to get that string. Which is not a good approach.
I want to send that string to DAL plugin via Operating System supported IPC(Inter Process Communication).
But there are many ways to do IPC on MacOS like
Apple Events
Distributed Notifications in Cocoa
BSD Notifications
Transferring Raw Data With CFMessagePort
Communicating With BSD Sockets
Communicating With BSD Pipes
In my case I just want one way communication from a application to DAL Plugin.
I am new to MacOS development so not sure which approch will be efficiant and best for my case of one way comminucation from Application to DAL Plugin?