The profiles command shows them, but the Store file/directory is blocked off from access (which, I suppose, kinda makes sense).
(We are in the process of getting customers to upgrade the profile, and if I can see whether our profile has an entry, then I can behave differently.)
Selecting any option will automatically load the page
Post
Replies
Boosts
Views
Activity
We added a packet filter to our app, then found a way to not need it, so we want to be able to remove it on upgrades. But we don't want to install it if it's not already installed. Simple, right?
The basic flow of the code is, on start-up, it does a propertiesRequestForExtensiion request. The method for the delegate goes through the various versions, ignoring any that are property.isEnabled == NO. When it comes to one that is enabled, it checks the version -- if it's the same version as the running app, it goes to deactivate it. If it's a different version, it goes to enable the current version (creating a activationRequestForExtensiion request).
This should all be very simple. Except.
At some point during this, the properties request gets a failure -- Domain=OSSystemExtensionErrorDomain Code=1. Ok, it seems there are lots of them laying around (I haven't rebooted in a while), and that method doesn't return once it finds one that is enabled. So maybe it doesn't like that.
And then the activation request that was submitted also fails, also with the same error that doesn't explain anything.
I thought, ok, maybe they don't like to stop on each other's toes, so let's create a serial dispatch queue, and have all of the system extension requests use that queue. That way, the activation request won't begin until the properties request has finished!
Only I did that. And it did get a bit further -- the request method was invoked! Only then I still got messages about the properties and activation requests failing with the same unknown error.
So then I looked at console. And sysextd is crashing, every time this happens. And then I dump all of the logs around that time, and look through them, and see... nothing.
I had hoped to end this with a description of how I achieved victory, but instead... I'm going to have to reboot and see if that solves the mysterious crashing of sysextd.
Two different crash patterns -- one an abort, the other complaining about a lock being corrupt or owning thread having exited. The first one is:
Thread 1 Crashed:: Dispatch queue: com.apple.root.default-qos.overcommit
0 libsystem_platform.dylib 0x18fc10244 _os_unfair_lock_corruption_abort + 88
1 libsystem_platform.dylib 0x18fc0b788 _os_unfair_lock_lock_slow + 332
2 libobjc.A.dylib 0x18f820c90 objc_sync_enter + 20
3 com.kithrup.TPProvider 0x100d2eee0 closure #3 in TPProvider.startProxy(options:completionHandler:) + 340
4 com.kithrup.TPProvider 0x100d2d980 thunk for @escaping @callee_guaranteed () -> () + 28
5 libdispatch.dylib 0x18fa31910 _dispatch_client_callout + 20
6 libdispatch.dylib 0x18fa34dc8 _dispatch_continuation_pop + 600
7 libdispatch.dylib 0x18fa48be4 _dispatch_source_latch_and_call + 420
8 libdispatch.dylib 0x18fa477b4 _dispatch_source_invoke + 832
9 libdispatch.dylib 0x18fa431f4 _dispatch_root_queue_drain + 392
10 libdispatch.dylib 0x18fa43a04 _dispatch_worker_thread2 + 156
11 libsystem_pthread.dylib 0x18fbdb0d8 _pthread_wqthread + 228
12 libsystem_pthread.dylib 0x18fbd9e30 start_wqthread + 8
while the other one is:
Application Specific Information:
BUG IN CLIENT OF LIBPLATFORM: os_unfair_lock is corrupt, or owner thread exited without unlocking
Abort Cause 198194
Thread 1 Crashed:: Dispatch queue: com.apple.root.default-qos.overcommit
0 libsystem_platform.dylib 0x18fc10220 _os_unfair_lock_corruption_abort + 52
1 libsystem_platform.dylib 0x18fc0b788 _os_unfair_lock_lock_slow + 332
2 libobjc.A.dylib 0x18f820c90 objc_sync_enter + 20
3 com.kithrup.TPProvider 0x104e86ee0 closure #3 in TPProvider.startProxy(options:completionHandler:) +340
4 com.kithrup.TPProvider 0x104e85980 thunk for @escaping @callee_guaranteed () -> () + 28
5 libdispatch.dylib 0x18fa31910 _dispatch_client_callout + 20
6 libdispatch.dylib 0x18fa34dc8 _dispatch_continuation_pop + 600
7 libdispatch.dylib 0x18fa48be4 _dispatch_source_latch_and_call + 420
8 libdispatch.dylib 0x18fa477b4 _dispatch_source_invoke + 832
9 libdispatch.dylib 0x18fa431f4 _dispatch_root_queue_drain + 392
10 libdispatch.dylib 0x18fa43a04 _dispatch_worker_thread2 + 156
11 libsystem_pthread.dylib 0x18fbdb0d8 _pthread_wqthread + 228
12 libsystem_pthread.dylib 0x18fbd9e30 start_wqthread + 8
Our TPProvider, whenever it uses a dispatch queue, uses a custom one, so these are presumably system queues and locks. My best guess would be some XPC command took too long? But that's just WAG.
Any ideas about what is actually going on?
Even when it is disabled (that is, our app says "don't do anything" and all it does is start logging things).
On the mac, when I try to make an outgoing audio-only call (it's a mac mini with no camera), it seems to connect as far as the outside is concerned, but nothing happens -- I get a request on my other devices, with the wrong account, and the mac mini says it's failed while the ipad or iphone keep connected.
I am logging everything I can think of in our extensions, and they don't seem to show anything of interest. And I can't figure out what to look for in the entirety of system logs. I do see Messages dropped during live streaming (use log show to see what they were)... but I'm not sure what to look for in the log show.
If I try to make a call in, it results in what seems to be an iOS FaceTime bug -- the phone tells me to log into FaceTime. Even though I am logged in.
This one is sorta behaving similar to the FaceTime / AirDrop issue, but it does depend on order, which makes me wonder if it's a programming choice. Specifically, using FortiNet's VPN client, using IPSec, if I have a TPP installed and then try to connect it, it fails. If, however, I connect and then start the TPP, it succeeds, which at least makes it better than FaceTime and AirDrop.
So my question here is... hm, not as well-articulated as I would like. I'm curious if a VPN can check to see if other VPNs are installed and configured, and if so say "nope." Hm, saying that more clearly: I think it's possible for a network extension to check the interface that a packet/flow is going to, and cause a failure of some sort if it's a VPN, correct? Does anyone do that? Or am I seeing lions in the waterhole weeds?
I'm also curious if Apple's networking code has issues with multiple VPNs. (Although, I will note, our TPP works just fine with Tailscale, so it's not an inherent conflict. Also Cisco AnyConnect. So maybe it's just IPSec?)
ETA: to make it clear, my test case involves using a ****** TPP, where handleNewUDPFlow and handleNewFlow both immediately return false, meaning that the system should behave as if it's not there, and yet... doesn't.
I appreciate any comments/assistance/guffaws.
On macOS, that is. The goals are largely for testing, where we'd like to know the maximum and minimum memory our processes are using, but we'd also like to know it on crash.
Our current method is to use ps periodically and grab the appropriate field, but is there a better way? (I looked at MetricKit, but it's not as useful on macOS; I filed FB13640765 "MetricKit would be awesome with more mac features" a couple of months ago.)
Because it may be quicker to ask: with a TPP, readData() gets a data size of 0 if the process has finished writing to the network. However, there seems to be no way to find out if it has finished reading from the network, other than to do a .write() and see if you get an error. (I filed a FB about this, for whatever that's worth.)
Since the API is flow-based, not socket, it's not possible to tell if the app has set its own timeout. Or exited. So one question I have is: if I do flow.write(Data(count:0)) -- is that a possible way to determine if it's still around? Or will it be interpreted as read(2) returning 0?
(Putting this in for testing is difficult, but not impossible -- as I said, this might be the quickest way to find out.)
I ran it (Leaks) on a process for about 2 hours. It collected 68gytes of data. It cannot open the folder -- can't find a file (which is there as a .zip archive) or if I expand it, just an error about missing an index.
Filing a bug about this is difficult, since it's 68gbyets of data.
As I've mentioned multiple times, we've discovered some very annoying failures when using a TPP, including FaceTime, AirDrop, and some VPNs. (Tailscale works fine, weirdly enough.) In doing some experimentation today with FortiNet, I was able to get the TPP to work if I added the FortiNet server (which, in our case, is an amazon VM) to the TPP's excludedNetworks list.
While it is not working, the tcpdump I got for the host was:
15:15:35.584029 IP (tos 0x0, ttl 64, id 1976, offset 0, flags [none], proto UDP (17), length 412)
192.168.43.16.55067 > ${hidden}.ipsec-msft: [udp sum ok] NONESP-encap: isakmp 1.0 msgid 00000000 cookie d66f571dcfc483ba->0000000000000000: phase 1 I ident:
(sa: doi=ipsec situation=identity
(p: #1 protoid=isakmp transform=2
(t: #1 id=ike (type=lifetype value=sec)(type=lifeduration len=4 value=00015180)(type=enc value=aes)(type=keylen value=0080)(type=auth value=fde9)(type=hash value=sha1)(type=group desc value=modp2048))
(t: #2 id=ike (type=lifetype value=sec)(type=lifeduration len=4 value=00015180)(type=enc value=aes)(type=keylen value=0100)(type=auth value=fde9)(type=hash value=sha2-256)(type=group desc value=modp2048))))
(vid: len=16 4a131c81070358455c5728f20e95452f)
(vid: len=16 8f8d83826d246b6fc7a8a6a428c11de8)
(vid: len=16 439b59f8ba676c4c7737ae22eab8f582)
(vid: len=16 4d1e0e136deafa34c4f3ea9f02ec7285)
(vid: len=16 80d0bb3def54565ee84645d4c85ce3ee)
(vid: len=16 7d9419a65310ca6f2c179d9215529d56)
(vid: len=16 cd60464335df21f87cfdb2fc68b6a448)
(vid: len=16 90cb80913ebb696e086381b5ec427b1f)
(vid: len=16 4c53427b6d465d1b337bb755a37a7fef)
(vid: len=16 b4f01ca951e9da8d0bafbbd34ad3044e)
(vid: len=8 09002689dfd6b712)
(vid: len=16 12f5f28c457168a9702d9fe274cc0100)
(vid: len=16 afcad71368a1f1c96b8696fc77570100)
E.......@.....+.6.8c......6......oW........................|...d...........X.......(..............Q........................(..............Q.........................J.....XE\W(...E/........m$ko....(.......C.Y..glLw7."........M...m..4......r........=.TV^.FE..\......}...S..o,....R.V.....`FC5.!.|...h..H........>.in.c...B{.....LSB{mF].3{.U.z..........Q.......J..N.... .&.............Eqh.p-..t...........h...k...wW..
15:15:35.901666 IP (tos 0x0, ttl 46, id 23154, offset 0, flags [none], proto UDP (17), length 272)
${hidden}.ipsec-msft > 192.168.43.16.55067: [udp sum ok] NONESP-encap: isakmp 1.0 msgid 00000000 cookie d66f571dcfc483ba->d1ec3b9d2f311bf5: phase 1 R ident:
(sa: doi=ipsec situation=identity
(p: #1 protoid=isakmp transform=1
(t: #1 id=ike (type=lifetype value=sec)(type=lifeduration len=4 value=00015180)(type=enc value=aes)(type=keylen value=0080)(type=auth value=fde9)(type=hash value=sha1)(type=group desc value=modp2048))))
(vid: len=16 4a131c81070358455c5728f20e95452f)
(vid: len=16 afcad71368a1f1c96b8696fc77570100)
(vid: len=8 09002689dfd6b712)
(vid: len=16 12f5f28c457168a9702d9fe274cc0204)
(vid: len=16 4c53427b6d465d1b337bb755a37a7fef)
(vid: len=16 8299031757a36082c6a621de00000000)
(vid: len=16 9b15e65a871aff342666623ba5022e60)
(vid: len=16 ca4a4cbb12eab6c58c57067c2e653786)
E...Zr......6.8c..+.......Z>.....oW.......;./1.................<...........0.......(..............Q.........................J.....XE\W(...E/........h...k...wW...... .&.............Eqh.p-..t.......LSB{mF].3{.U.z..........W.`...!............Z...4&fb;...`.....JL......W.|.e7.
15:15:35.901756 IP (tos 0x0, ttl 64, id 41586, offset 0, flags [none], proto ICMP (1), length 56)
192.168.43.16 > ${hidden}: ICMP 192.168.43.16 udp port 55067 unreachable, length 36
IP (tos 0x0, ttl 46, id 23154, offset 0, flags [none], proto UDP (17), length 272)
${hidden}.ipsec-msft > 192.168.43.16.55067: [no cksum] [|isakmp_rfc3948]
`.....<"..:...E..8.r..@.}q..+.6.8c...Q....E...Zr......6.8c..+.........
15:15:38.904628 IP (tos 0x0, ttl 46, id 23155, offset 0, flags [none], proto UDP (17), length 272)
${hidden}.ipsec-msft > 192.168.43.16.55067: [udp sum ok] NONESP-encap: isakmp 1.0 msgid 00000000 cookie d66f571dcfc483ba->d1ec3b9d2f311bf5: phase 1 R ident:
(sa: doi=ipsec situation=identity
(p: #1 protoid=isakmp transform=1
(t: #1 id=ike (type=lifetype value=sec)(type=lifeduration len=4 value=00015180)(type=enc value=aes)(type=keylen value=0080)(type=auth value=fde9)(type=hash value=sha1)(type=group desc value=modp2048))))
(vid: len=16 4a131c81070358455c5728f20e95452f)
(vid: len=16 afcad71368a1f1c96b8696fc77570100)
(vid: len=8 09002689dfd6b712)
(vid: len=16 12f5f28c457168a9702d9fe274cc0204)
(vid: len=16 4c53427b6d465d1b337bb755a37a7fef)
(vid: len=16 8299031757a36082c6a621de00000000)
(vid: len=16 9b15e65a871aff342666623ba5022e60)
(vid: len=16 ca4a4cbb12eab6c58c57067c2e653786)
E...Zs......6.8c..+.......Z>.....oW.......;./1.................<...........0.......(..............Q.........................J.....XE\W(...E/........h...k...wW...... .&.............Eqh.p-..t.......LSB{mF].3{.U.z..........W.`...!............Z...4&fb;...`.....JL......W.|.e7.
15:15:38.904763 IP (tos 0x0, ttl 64, id 8956, offset 0, flags [none], proto ICMP (1), length 56)
192.168.43.16 > ${hidden}: ICMP 192.168.43.16 udp port 55067 unreachable, length 36
IP (tos 0x0, ttl 46, id 23155, offset 0, flags [none], proto UDP (17), length 272)
${hidden}.ipsec-msft > 192.168.43.16.55067: [no cksum] [|isakmp_rfc3948]
`.....<"..:...E..8"...@.....+.6.8c...Q....E...Zs......6.8c..+.........
So, given that, I tried adding
let msftIPSecHost = NWHostEndpoint(hostname: "", port: "4500")
let msftIPSecRule = NENetworkRule(destinationNetwork: msftIPSecHost, prefix: 0, protocol: .any)
settings.excludedNetworkRules = [msftIPSecRule]
and... it worked. At least, the fortinet client worked, and AirDrop transmission worked.
Note that I never saw the flows for port 4500 in handleNewUDPFlow(:initialRemoteEndpoint:) -- just having a UDP rule that would intercept them seems to have caused it to fail.
Anyone encountered this, or have an explanation? (I am now trying it in our actual product to see how it works.)
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?
I'm mostly thinking of a Transparent Proxy Provider, as usual, but... how does one test it? I can't see how one would do it with unit tests (although you could break out code and test some of that code). Since it requires MDM or user approval, that makes automated tests a bit difficult. I have this monstrous vision of writing a program that loads the extension and invokes the appropriate methods on it but that just leads to other questions about subclasses.
I'm sure other people have thought about this and am curious what the thoughts are. 😄
This doesn't particularly surprise me, but I am curious about it, and whether we can change it: our TPP won't start if the only IP address available is in 169.254.0.0/16. I can see (from our logs) that the preferences are loaded & saved, and the extension is loaded, but until it gets a real address, the startProxy method is not invoked.
First, for the employees reading, I filed FB14844573 over the weekend, because this is a reproducible panic or hang. whee
I ran our stress tests for an entire long weekend, and my machine panicked, due to mbufs. Normally, I tell my coworkers that we can't really do anything to cause a panic -- but we're doing network things, so this is an exception. I started periodically testing the mbufs while the tests were running -- netstat -m | grep 'mbufs in use' -- and noticed that in fact they were going up, and never decreasing. Even if I killed our code and uninstalled the extensions. (They're increasing at about ~4mbufs/sec.)
Today I confirmed that this only happens if we include UDP packets:
let udpRule = NENetworkRule(destinationNetwork: host, prefix: 0, protocol: .UDP)
let tcpRule = NENetworkRule(destinationNetwork: host, prefix: 0, protocol: .TCP)
...
settings.includedNetworkRules = [udpRule, tcpRule]
If I comment out that udpRule, part, mbufs don't leak.
Our handleNewUDPFlow(:, initialRemoteEndpoint:) method checks to see if the application is a friendly one, and if so it returns false. If it isn't friendly, we want to block QUIC packets:
if let host = endpoint as? NWHostEndpoint {
if host.port == "80" || host.port == "443" {
// We need to open it and then close it
flow.open(withLocalEndpoint: nil) { error in
Self.workQueue.asyncAfter(deadline: .now() + 0.01) {
let err = error ?? POSIXError(POSIXErrorCode.ECONNABORTED)
flow.closeReadWithError(err)
flow.closeWriteWithError(err)
}
}
return true
}
}
return false
Has anyone else run into this? I can't see that it's my problem at that point, since the only thing we do with UDP flows is to either say "we don't want it, you handle it" or "ok sure, we'll take it but then let's close it immediately".
This is definitely a weird one -- the laptop is running macOS 12, but it's trying to build using macOS 13 SDK? (The machine cannot run anything later than macOS 12, btw.)
In file included from /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/System/Library/Frameworks/CoreFoundation.framework/Headers/CFStream.h:20:
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX13.1.sdk/usr/include/dispatch/dispatch.h:69:10: fatal error:
'dispatch/block.h' file not found
#include <dispatch/block.h>
^~~~~~~~~~~~~~~~~~
1 error generated.
I'm trying xcode-select --install but has anyone run into this before?
I'm playing around with using an app to automate some of my personal work flows, and one of the things I wanted to do was to be able to drag a .webloc file onto my app icon in the dock, to launch it.
I've got public.data set up as a document type for it in Xcode, which translated to
<key>CFBundleDocumentTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Default</string>
<key>LSItemContentTypes</key>
<array>
<string>public.data</string>
</array>
</dict>
</array>
in the Info.plist for it, which seems correct. When I drag a .webloc file onto the Dock icon, it appears to be willing to accept it, but nothing seems to happen.
In the app, I've got an AppDelegate.swift file which has
extension Notification.Name {
static let receivedURLsNotification = Notification.Name("ReceivedURLsNotification")
}
class AppDelegate: NSObject, NSApplicationDelegate {
func application(_ application: NSApplication, open urls: [URL]) {
guard !urls.isEmpty else { return }
NotificationCenter.default.post(name: .receivedURLsNotification, object: nil, userInfo: ["URLs": urls])
}
}
(I copied it almost verbatim from a Medium post.)
In the app swift file, I have
@main
struct LoggerApp: App, DropDelegate {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
I set a breakpoint on application(_:NSApplication, open:[URL]), and did my drag, and the breakpoint never triggered.
I added the application(didFinishLaunching(_:Notification) method, and that does get invoked when the app launches, so the app delegate does seem to be working. That seems to indicate the problem is somewhere else?