bytes is the UnsafeRawPointer the NEFilterPacketProvider handler gets from the system. The values of etherHeaderSize and ip4HeaderSize are the expected 14 and 20, respectively.
I feel like I am missing something very obvious here.
So clearly the pointer is wrong. I'm not sure why it's wrong, though. But looking at the packet (bytes + etherHeaderSize), I find the IPv4 header as expected, and then the UDP header as expected.
Post not yet marked as solved
The specific line is the guard statement, so yeah, I was going to try to break it up. However, I disassembled at one point:
* At +521, %r13 is 0x0.
* Redirector.o[0x8c70] <+512>: callq 0x8c75 ; <+517> [inlined] Redirector.flowSets.getter : Swift.Dictionary<Foundation.UUID, FlowData> + 27 at Redirector.swift:651:43
* Redirector.o[0x8c75] <+517>: movq (%r14,%rbx), %r13
* Redirector.o[0x8c79] <+521>: cmpq $0x0, 0x10(%r13)
* Redirector.o[0x8c7e] <+526>: je 0x8d35 ; <+709> at Redirector.swift:651:43
So I assume that %r13 has self.flowSets[id] (rather than id). For some reason, however, I didn't disassemble enough to have %r14 and %rbx annotated.
Ok, that's what I thought. 😄 (And what I am doing.)
Post not yet marked as solved
We use cmake, so it was a bit more difficult -- and CircleCI, so I had to make sure the dsym files got archived. Did that. Re-confirmed it's this code:
guard let flowData = self.flowSets[id] else {
os_log(.error, log: Self.log, "Could not find flow %{public}@", id.uuidString);
completion(RedirectorError.flowNotFound)
return
}
id is a UUID; self.flowSets is private var flowSets : [UUID : FlowData] = [:] (where FlowData is a simple class wrapping some flow-related information). This particular method is invoked via XPC from a daemon, with a signature of func handleTCPData(_ id: UUID, data: Data?, completion: @escaping (_: Error?) -> Void). The daemon code is in ObjC++, and it checks to ensure that the UUID is non-nil.
So I have no idea why it is segfaulting!
Ah! NEFilterDataProvider!
As I said, I figured out that it's the level 2 ethernet, not level 1. I get tunnel vision sometimes.
Ah. If it's just
struct ether_header {
u_char ether_dhost[ETHER_ADDR_LEN];
u_char ether_shost[ETHER_ADDR_LEN];
u_short ether_type;
} __packed;
then it makes sense.
Post not yet marked as solved
I meant "copying the signing command." :)
Post not yet marked as solved
Also, is there a better way of getting the line number from the address than using lldb or objdump to disassemble with lines? ;) It's hit and miss, unfortunately.
Post not yet marked as solved
I tried thread sanitizer, unfortunately it fails too much on the 3rd party C++ code the project uses.
The Swift method in question here has a closer which itself has a closure.
Post not yet marked as solved
Oh, and the textified version.
next-crash.txt
Post not yet marked as solved
Here's the raw-ish IPS. I'm sure concurrency is the problem.
next.ips
Post not yet marked as solved
None of the arguments is ever modified by something else; the most that happens is that references are added and removed. sigh.
Post not yet marked as solved
Now, this still leaves me wondering how to combine them into a single bundle. I mean, I know how to script the part where I lipo the various parts together, but I'm not sure how to get the proper signing done, other than copying the output of xcodebuild. We can have separate distributions for now (until and unless Apple lets me use the Endpoint Security Framework for real, we can't be feature-complete, or at least feature-parity with Windows, anyway).
Post not yet marked as solved
Over, on twitter, Alexander Neumann (@Iluinrandir) gave me the solution. I used
env PATH=${HOME}/vcpkg-arm64:${PATH} cmake -G Xcode .. -DVCPKG_HOST_TRIPLET=x64-osx -DVCPKG_TARGET_TRIPLET=arm64-osx -DCMAKE_TOOLCHAIN_FILE=${HOME}/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_OSX_ARCHITECTURES=arm64 -DMACOS_BUILD_RELEASE=ON
to create the xcodeproj, and then time cmake --build . --config Release -- -allowProvisioningUpdates to build. And... I ended up with arm64 executables that work on my M1 MBP.
I'm not sure if the -DCMAKE_OSX_ARCHITECTURES=arm64 is necessary or not.