Post

Replies

Boosts

Views

Activity

Network extension crash during process startup.
Hi, I've developed network extension that is being loaded from container application. Currently, i'd like to test the extension using development profile in signature. I've implemented 4 providers inside the extension, each derived from NE basic class. here are the definitions of my providers : @interface myAppProxyProvider : NEAppProxyProvider @interface myFilterDataProvider : NEFilterDataProvider @interface myFilterPacketProvider : NEFilterPacketProvider @interface myDnsProxyProvider : NEDNSProxyProvider and added them in the Info.plist accordingly: <key>NetworkExtension</key> <dict> <key>NEMachServiceName</key> <string>MY_TEAM_ID.com.myBrand.ext</string> <key>NEProviderClasses</key> <dict> <key>com.apple.networkextension.app-proxy</key> <string>myAppProxyProvider</string> <key>com.apple.networkextension.dns-proxy</key> <string>myDnsProxyProvider</string> <key>com.apple.networkextension.filter-data</key> <string>myFilterDataProvider</string> <key>com.apple.networkextension.filter-packet</key> <string>myFilterPacketProvider</string> </dict> </dict> I also gave the extension proper entitlements, that my developer provision profile supports. <dict> <key>com.apple.application-identifier</key> <string>MY_TEAM_ID.com.myBrand.ext</string> <key>com.apple.developer.networking.networkextension</key> <array> <string>app-proxy-provider</string> <string>content-filter-provider</string> <string>packet-tunnel-provider</string> <string>dns-proxy</string> <string> </array> <key>com.apple.developer.team-identifier</key> <string>MY_TEAM_ID</string> <key>com.apple.security.application-groups</key> <array> <string>MY_TEAM_ID.myGroup.com</string> </array> <key>com.apple.security.network.client</key> <true/> <key>com.apple.security.network.server</key> <true/> </dict> First, I activate the extension from the container app, so it set to [activated enabled] Then, In order to spawn the xpc client process, I start the xpc connection from the container application. but the process gets immediate exception and crash right after startup for the following reason : System Integrity Protection: enabledCrashed Thread:       0 Dispatch queue: com.apple.main-threadException Type:       EXC_BREAKPOINT (SIGTRAP) Exception Codes:      0x0000000000000001, 0x00000001aab620f8 Exception Note:       EXC_CORPSE_NOTIFYTermination Reason:   Namespace SIGNAL, Code 5 Trace/BPT trap: 5 Terminating Process:  exc handler [1268]Application Specific Information: Configuration error: Couldn’t retrieve XPCService dictionary from service bundle. The problem may hint wrong configuration of the Info.plist, no ? Any idea what can lead to this ? Thanks
2
0
1.2k
Aug ’22
Mixing NEDNSProxyProvider and NEAppProxyProvider create problems sending DNS requests
Hi, I'm using 2 separated providers, each derived from dns and application providers respectively. in the application provider I use the object NETunnelNetworkSettings as input in method to setTunnelNetworkSettings to catch all network data originated from some specific applications (including dns packets). in the dns provider I'd like to catch all dns traffic in general disregarding any specific application where the request was originated from. in my experiment, If I avoid setting the DNS server addresses in DNSSettings inside NETunnelNetworkSettings, than all DNS originated from the specific application I set using the app proxy tunnel, will be destined to address 10.0.0.10 by default (and not the default DNS address). However, If I do set this DNSSettings value, I get the following block (in my example I set the app proxy to catch the traffic of zoom.us application) 2023-04-19 11:34:45.493033+0300 0x1206 Default 0x0 501 0 mDNSResponder: [com.apple.mDNSResponder:Default] [Q36288] ShouldSuppressUnicastQuery: Query suppressed for zoom.us. Addr (blocked by policy) 2023-04-19 11:34:45.493582+0300 0x1206 Default 0x0 501 0 mDNSResponder: [com.apple.mDNSResponder:Default] [Q14787] ShouldSuppressUnicastQuery: Query suppressed for zoom.us. AAAA (blocked by policy) my desire is to catch the application connections using the app proxy provider, and leave the dns requests/responses for the dns proxy provider. I know this might not be the best approach, but perhaps there's a way to "tell" my application proxy provider to "ignore" DNS packets on udp connection, and let the DNS proxy handle it (without getting blocked by policy error, which happen before the packet reaches any of the proxy providers.) thanks !
2
0
959
Apr ’23
MTU cache doesn't gets updated when PMTU is set.
HI, I've created a virtual interface that used to get all outgoing packets, encapsulate with some VPN header, before resend them to their final destination through the physical adapter. In order to choose the optimal MTU size that won't trigger fragmentation, I'd like to calculate the PMTU between the physical interface and the destination, subtracted by the encapsulation header size. Then I'll set the virtual adapter's MTU with this result. In order to do so, I poll the overall MTU cache using sysctl on macOS. First, I verified that path mtu discovery is set sysctl net.inet.tcp.path_mtu_discovery net.inet.tcp.path_mtu_discovery: 1 Then, I tried to extract the cached pmtu for the gateway from the other size of the tunnel using the routing table . static constexpr auto kSysctlMibLength = 6; void get_pmtu_cache() { std::map<std::string, std::uint32_t> res; size_t size_needed = 0; std::vector<char> route_table; std::array<int, kSysctlMibLength> mib; char *next = nullptr; char *lim = nullptr; struct rt_msghdr *rtm = nullptr; struct sockaddr *saddr = nullptr; struct sockaddr_in *sockin = nullptr; char dest_ip_address[INET6_ADDRSTRLEN]; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; // stage 1 : get the routing table // get routing table size if (sysctl(mib.data(), kSysctlMibLength, nullptr, &size_needed, nullptr, 0) < 0) { return; } // allocate local var according to size route_table.reserve(size_needed); // get routing table contents if (sysctl(mib.data(), kSysctlMibLength, route_table.data(), &size_needed, nullptr, 0) < 0) { return; } In the next step, I simple iterate the routing table elements and extract the following field for each destination : rt_msghdr.rt_metrics.rmx_mtu which is the path MTU from current endpoint to dest address. lim = route_table.data() + size_needed; for (next = route_table.data(); next < lim; next += rtm->rtm_msglen) { rtm = reinterpret_cast<struct rt_msghdr *>(next); saddr = reinterpret_cast<struct sockaddr *>(rtm + 1); if ((rtm->rtm_addrs & RTA_DST) != 0) { sockin = reinterpret_cast<struct sockaddr_in *>(saddr); if (nullptr == inet_ntop(saddr->sa_family, &sockin->sin_addr.s_addr, dest_ip_address,INET6_ADDRSTRLEN)) { continue; } const std::string dest_ip_address_str(dest_ip_address, strlen(dest_ip_address)); auto iter = res.find(dest_ip_address_str); if (iter == res.end() || iter->second > rtm->rtm_rmx.rmx_mtu) { res.insert_or_assign(dest_ip_address_str, rtm->rtm_rmx.rmx_mtu); } } } when I finally print all the values in res I see that my pmtu to my VPN server is 1500, even-though I've set the server's mtu size to 1000, and I check that ping -D -s 1500 <server> doesn't work since packets from size 1500 that cannot be fragmanted won't work. auto item = res.find(vpn_server_address); if (item == res.cend()) { printf("no pmtu found to %s\n", vpn_server_address ); return; } ret = item->second; I've tried to trigger the pmtu discovery to the VPN server using nscurl by sending https requests there, but the pmtu still remained on 1500. Perhaps I'm missing something ? do I extract the pmtu correctly ? do I trigger the pmtu discovery by sending https messages using nscurl which is based on NSURLSession ? Thanks !
2
0
987
Aug ’23
Application signed with ability to load system extensions started failing due to signature issue
Hi, I've developed an application which reside under /Applications. Inside the main application bundle (/Applications/mainApp.app) there are sub-app that contain security extension. Here's the relevant path /Applications/mainApp.app/Contents/Helpers/subApp.app/Contents/Library/SystemExtensions/com.myComp.type.systemextension/ So far I could load the extension by running the subApp and make sure it calls the extension activation API. but seems like starting from Sonoma (i'm using version 14.6.1 )it stopped working, and I get crash dump on signature failure which trying to open the subApp.app. in the crash log I get reason of invalid code sign. I also get the following hints Binary Images: 0x1050a0000 - 0x10512bfff dyld_path_missing (*) <f635824e-318b-3f0c-842c-c369737f2b68> /dyld_path_missing 0x104d9c000 - 0x104d9ffff main_executable_path_missing (*) <1df5f408-cb16-304f-8b38-226e29361161> /main_executable_path_missing Is it possible that new OS version have new validation rule that enforce something about the location of the app that can start extensions ?
2
0
809
Sep ’24
SwiftUI based application gets stuck on deadlock
Hi, I get a weird deadlock in my swiftUI based application where com.apple.libtrace.state.block-list is waiting on com.apple.main-thread any idea what can lead to this deadlock ? also, what is com.apple.libtrace.state.block-list used for ? When deadlock occurs, the main thread it stucks on publishing property change that triggers callback function. for example : # definition @Published var event: eventType = .evtTypeWhatever ... # setting that may linked to the deadlock : self.handler.event = eventType.evtSomething; # callback definition .onReceive(cbhandler.$event, perform: eventReceived) # implementation : private func eventReceived(_ type:eventType) { switch type { case .evtSomething: # do something Here's the relevant callstack. We can see that It even didn’t get to the callback. The deadlock is probably in publishing mechanism itself 2480 Thread_87233850 DispatchQueue_1: com.apple.main-thread (serial) + 2480 start (in dyld) + 6076 [0x197c92b98] + 2480 __debug_main_executable_dylib_entry_point (in myAgent.debug.dylib) + 12 [0x10402fc38] myApp.swift:0 + 2480 static networkWrapperAppApp.$main() (in myAgent.debug.dylib) + 40 [0x10402fbf8] /<compiler-generated>:0 + 2480 static App.main() (in SwiftUI) + 224 [0x1c8b2a5c0] + 2480 runApp<A>(_:) (in SwiftUI) + 108 [0x1c87c9658] + 2480 specialized runApp(_:) (in SwiftUI) + 160 [0x1c836b878] + 2480 NSApplicationMain (in AppKit) + 880 [0x19c00d35c] + 2480 -[NSApplication run] (in AppKit) + 480 [0x19c036c64] + 2480 -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] (in AppKit) + 688 [0x19c9e25b0] + 2480 _DPSNextEvent (in AppKit) + 684 [0x19c043ab4] + 2480 _BlockUntilNextEventMatchingListInModeWithFilter (in HIToolbox) + 76 [0x1a3d3e484] + 2480 ReceiveNextEventCommon (in HIToolbox) + 676 [0x1a3bb34e8] + 2480 RunCurrentEventLoopInMode (in HIToolbox) + 324 [0x1a3bb027c] + 2480 CFRunLoopRunSpecific (in CoreFoundation) + 572 [0x19811bc58] + 2480 __CFRunLoopRun (in CoreFoundation) + 1980 [0x19811ca9c] + 2480 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ (in CoreFoundation) + 16 [0x19815bda4] + 2480 _dispatch_main_queue_callback_4CF (in libdispatch.dylib) + 44 [0x197e89cec] + 2480 _dispatch_main_queue_drain (in libdispatch.dylib) + 180 [0x197e89db0] + 2480 _dispatch_main_queue_drain.cold.5 (in libdispatch.dylib) + 812 [0x197eb1b58] + 2480 _dispatch_client_callout (in libdispatch.dylib) + 16 [0x197e9485c] + 2480 _dispatch_call_block_and_release (in libdispatch.dylib) + 32 [0x197e7ab2c] + 2480 thunk for @escaping @callee_guaranteed () -> () (in myAgent.debug.dylib) + 48 [0x103f44a3c] /<compiler-generated>:0 + 2480 closure #1 in closure #9 in AppDelegate.applicationDidFinishLaunching(_:) (in myAgent.debug.dylib) + 24508 [0x10401625c] /<compiler-generated>:0 + 2480 callbackHandler.currPage.modify (in myAgent.debug.dylib) + 44 [0x103ff84ec] /<compiler-generated>:0 + 2480 callbackHandler.currPage.setter (in myAgent.debug.dylib) + 204 [0x103ff8470] myApp.swift:81 + 2480 callbackHandler.currentPage.setter (in myAgent.debug.dylib) + 120 [0x103ff7850] myApp.swift:0 + 2480 static Published.subscript.setter (in Combine) + 84 [0x1abbe3500] + 2480 specialized static Published.subscript.setter (in Combine) + 60 [0x1abbe4648] + 2480 specialized static Published.withMutation<A>(of:keyPath:storage:apply:) (in Combine) + 556 [0x1abbe45b0] + 2480 closure #1 in static Published.subscript.setter (in Combine) + 428 [0x1abbe3724] + 2480 PublishedSubject.send(_:) (in Combine) + 192 [0x1abbbc558] + 2480 ObservableObjectPublisher.send() (in Combine) + 636 [0x1abbd18fc] + 2480 ObservableObjectPublisher.Inner.send() (in Combine) + 176 [0x1abbd2244] + 2480 _os_unfair_lock_lock_slow (in libsystem_platform.dylib) + 176 [0x19806a324] + 2480 __ulock_wait2 (in libsystem_kernel.dylib) + 8 [0x197ffea54] 2480 Thread_87263447 DispatchQueue_22: com.apple.libtrace.state.block-list (serial) + 2480 start_wqthread (in libsystem_pthread.dylib) + 8 [0x19802db74] + 2480 _pthread_wqthread (in libsystem_pthread.dylib) + 292 [0x19802ee64] + 2480 _dispatch_workloop_worker_thread (in libdispatch.dylib) + 540 [0x197e8dae8] + 2480 _dispatch_root_queue_drain_deferred_wlh (in libdispatch.dylib) + 292 [0x197e8e264] + 2480 _dispatch_lane_invoke (in libdispatch.dylib) + 440 [0x197e83e60] + 2480 _dispatch_lane_serial_drain (in libdispatch.dylib) + 740 [0x197e83350] + 2480 _dispatch_client_callout (in libdispatch.dylib) + 16 [0x197e9485c] + 2480 _dispatch_call_block_and_release (in libdispatch.dylib) + 32 [0x197e7ab2c] + 2480 ___os_state_request_for_self_block_invoke (in libsystem_trace.dylib) + 372 [0x197d827a8] + 2480 _dispatch_sync_f_slow (in libdispatch.dylib) + 148 [0x197e8a640] + 2480 __DISPATCH_WAIT_FOR_QUEUE__ (in libdispatch.dylib) + 368 [0x197e8aa88] + 2480 _dispatch_thread_event_wait_slow (in libdispatch.dylib) + 56 [0x197e7cadc] + 2480 _dlock_wait (in libdispatch.dylib) + 56 [0x197e7ccbc] + 2480 __ulock_wait (in libsystem_kernel.dylib) + 8 [0x197ff29b8]
Topic: UI Frameworks SubTopic: SwiftUI
2
0
100
Oct ’25
LaunchDaemon plist file cannot run script due to permission issue
Hi, I've created persistent task from type launchDaemon based on bash script that should run one time upon first load. These are the contents of the plist file : &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt; &lt;plist version="1.0"&gt; &lt;dict&gt; &lt;key&gt;Label&lt;/key&gt; &lt;string&gt;com.blabla.task&lt;/string&gt; &lt;key&gt;RunAtLoad&lt;/key&gt; &lt;true/&gt; &lt;key&gt;LaunchOnlyOnce&lt;/key&gt; &lt;true/&gt; &lt;key&gt;Program&lt;/key&gt; &lt;string&gt;/Library/Application\ Support/myComp /script.sh&lt;/string&gt; &lt;/dict&gt; &lt;/plist&gt; However, when i load the plist using launchCtl, nothing happens and no meaningful log appears... However, when the Program location changes to /tmp/script.sh then everything is working great So i conclude that there's permission issue to access Library/Application\ Support, although the file permission is allow for all -rwxrwxrwx. But when I give back full disk access in privacy setting, it's working from the /Library.. path. My question is why does bash launchd task that runs with privileges, also requires this privacy acknowledge in order to run the script?
1
0
892
Jun ’21
Xcode integration with clang-tidy
Hi, I'm looking for a way to integrate clang-tidy rules with my xcode project. is there a way xcode can read .clang-tidy files and add the rules to each compilation line ? I couldn't find anyway to do it, so i presume it's unsupported. but perhaps there can be some workaround i can use to modify the compilation according to clang-tidy rules that the IDE read from a file. thanks !
1
2
2.3k
Oct ’21
macOS : programmatic check process creation context from within the process.
I'd like to get an indication about the context in which my process is running from. I'd like to distinguish between the following cases : It runs as a persistent scheduled task (launchDaemon/launchAgent) It was called on-demand and created by launchd using open command-line or double-click. It was called directly from command-line terminal (i.e. &gt; /bin/myProg from terminal ) Perhaps is there any indication about the process context using Objective-c/swift framework or any other way ? I wish to avoid inventing the wheel here :-) thanks
1
0
1.1k
Dec ’21
Implement swift API for C++ multi-type structure
Consider a C++ method that retrieve struct of native typed arguments like enum class, sub-structs, std::string, int, etc... I'd like to create a swift API that return the same struct but in swift variables for example : class ErrorMessage { public: int status; std::string message; }; class serverResponse { public: ErrorMessage error; std::string str_value; std::uint16_t int_val; std::time_t last_seen; EnumVal status; }; serverResponse getServerResponse(); So I'd like to convert it to the swift equivalent struct with native members open class serverResponseSwift : NSObject { open class var error: ErrorMessage { get } open var str_value: String { get } open var int_val: UInt16 { get } open var status: EnumVal { get } }; I know that direct conversion is not yet possible so I need to use objective-C++ code as a mediator. So I've used a bridging header to include the converting method in objective-C++ which will look like this : @interface Converter - (serverResponseSwift) getServerStatusSwift; @end and the equivalent .mm file will implement the conversion function, but can I use the swift Class in objective-c in order to fill it up according to the CPP serverResponse ? @implementation Converter - (serverResponseSwift) getServerStatusSwift { serverResponse x = getServerResponse(); /// How do I create serverResponseSwift out of serverResponse } Thanks !
1
0
1.2k
Dec ’21
Start XPC service outside the main loop
Hi, I was wondering if there's any limitation for the context where I initialize my xpc service. This is the code that initialize my xpc service : listener_ = [[NSXPCListener alloc] initWithMachServiceName:@"com.bla.bla"]; xpcService *delegate = [xpcService new]; listener_.delegate = delegate; [listener_ resume];  [[NSRunLoop mainRunLoop] run]; Doing it from the main method and everything works just fine. However, when calling it from different method(main)/thread(main thread)... It doesn't accept remote calls although it seems like the listener was properly initialized. I even tried to wrap this code to run on the main thread using the following wrapper dispatch_sync(dispatch_get_main_queue(), ^{ listener_ = [[NSXPCListener alloc] initWithMachServiceName:@"com.bla.bla"]; xpcService *delegate = [xpcService new]; listener_.delegate = delegate; [listener_ resume]; } where the [[NSRunLoop mainRunLoop] run]; is called from the main method... So my question is what are the requirements to make the XPC work.. is it mandatory to call it from the main method ?
1
0
1.1k
Jan ’22
Unregister Reachability event
Hi, I'm using the reachability framework in order to register network status event for a specific address (address_st in the code below)... I'd like to support change of address which will trigger unregister from the old address and register to the new one. How can it be done ? SCNetworkReachabilityRef reachabilityRef = SCNetworkReachabilityCreateWithAddress(NULL, reinterpret_cast&lt;sockaddr *&gt;(&amp;address_st)); SCNetworkReachabilityContext context = {0, NULL, NULL, NULL, NULL}; SCNetworkReachabilitySetCallback(reachabilityRef, ReachabilityCallback, &amp;context)) SCNetworkReachabilitySetDispatchQueue(reachabilityRef, dispatch_queue_create("com.reachability.test", nil)); thanks,
1
0
1k
Jun ’22
implement path mtu discovery.
Hi, I've like to calculate the path mtu between one of the local interfaces and a remote address. Perhaps there's such option using native networking framework like nsurlconnection ? Should I need to set the DF (don't fragment) bit and send to each hop in the path, or can I acquire this value from some cached storage per connection ? thanks
1
0
1.4k
Jul ’22
Getting old filesystem events - check which process deleted a specific folder
After macOS minor upgrade of Monterey I've noticed that a directory of mine that lies under /Library/Application Support/myCompany/myProj/myFolder has been mysteriously deleted. Is there a way to check in retrospect which process deleted my directory ? I know of fs_usage, but it's used to record ongoing file activities... the question is how to get file auditing event from the past. Thanks
1
0
1.1k
Dec ’22
macOS, call uninstall script when drag-and-drop app into the trash icon
I'm working on some app that has LaunchDaemon running on the background, and thus it requires some operations to be removed, prior to deleting the data/exe files. Is there an option to call an uninstall script upon drag-and-drop my app into the trash bin ? or at least, prevent the uninstallation and trigger popup window that tells the user this app cannot be removed until he unload the service (sudo launchctl stop /Library/LaunchDaemons... or sudo launchctl unload -w /Library/LaunchDaemons...) my app uses pkg file format for deployment, but I couldn't find any uninstall callback within this format. is there a way to do so ? Thanks
1
0
1.5k
Dec ’22
How to enable multiple proxy managers waiting for user approval event before execute SaveToPreferences completionHandler
I have a MacOS network extension that activates 3 network "Proxies" (TransparentProxy, AppProxy and DNSProxy). To activate the proxies I do: NEAppProxyProviderManager.loadAllFromPreferences { saveToPreferences { error in if (error) { /* failed to save */ } /* saved */ } } Now I do this 3 times (once for each proxy). The behavior I observe is the following: Once the "saveToPreferences()" is called for the first time the app is installed, user gets an approval popup. Even before user clicks anything, the first 2 calls to "saveToPreferences" fail (both with the same message): Failed to save configuration MyTransparentProxy: Error Domain=NEConfigurationErrorDomain Code=10 “permission denied” UserInfo={NSLocalizedDescription=permission denied} The third call to "saveToPreferences()" does NOT return until a user either accepts or rejects the "allow vpn configuration" pop up. My question is, how can I make all the calls to block the completion callback until user decision ? For now, I figured out that this works as workaround: In the initialization of the first proxy I do: NEAppProxyProviderManager.loadAllFromPreferences { saveToPreferences { error in if (error) { /* failed to save */ } /* saved */ /* here I start the “next” proxies */ StartNextProxy(); } } In this case the first one is blocked until user accepts the pop up and once he does I start the second and the third proxies. This ensure avoidance of "permission denied" error as only one "saveToPreferences()" call waits for user approval. This doesn’t feel like the correct method to me, is there a way for multiple proxy manager to wait for "VPN Configuration" approval event ? Thanks !
1
0
1.4k
Jan ’23