michaeleisel / zld

A faster version of Apple's linker
MIT License
1.19k stars 50 forks source link

Disabling code signing not working on arm64 simulator #98

Closed karlpuusepp closed 2 years ago

karlpuusepp commented 2 years ago

Our setup disables code signing from simulator builds (inspired by this excellent blog post)

So far this has worked fine, but when targeting arm64 simulators with zld and setting CODE_SIGNING_ALLOWED = NO the compiled app crashes on startup.

This does not affect Intel, nor does it happen when targeting Rosetta simulators (such as iOS 13). Apple's linker does not exhibit this issue.

bjorn3 commented 2 years ago

Doesn't macOS on M1 always require a signature, even if it is just an ad-hoc signature one?

karlpuusepp commented 2 years ago

I edited my initial post to clarify that Apple's linker does let us skip signing on M1 without issues. I don't know anything about M1 signing restrictions, though..

keith commented 2 years ago

I wonder if newer versions just ignore that setting. With the working binary what does codesign -dvvv path/to/binary output? Diffing that against what you get with zld might clear it up.

karlpuusepp commented 2 years ago

The setting is not strictly speaking ignored (the codesign steps are still missing in the compilation log for example) but you're right, the signing behaviours are different.

zld, signing disabled: app: code object is not signed at all

With signing disabled ld sets a linker-signed flag

CodeDirectory v=20400 size=4063 flags=0x20002(adhoc,linker-signed) hashes=124+0 location=embedded
...
Signature=adhoc
Info.plist=not bound
TeamIdentifier=not set
Sealed Resources=none
Internal requirements=none

ld, signing enabled:

CodeDirectory v=20400 size=4296 flags=0x2(adhoc) hashes=124+7 location=embedded
...
Signature=adhoc
Info.plist entries=26
TeamIdentifier=not set
Sealed Resources version=2 rules=10 files=17
Internal requirements count=0 size=12

I'm not sure if this is still a zld bug or not. Should it be expected to sign binaries like ld?

keith commented 2 years ago

I wouldn't be surprised if some things did change between the last open source dump that zld is based on and xcode 13ish.

michaeleisel commented 2 years ago

in the latest release of zld we see:

libcd_set_flags(_sigRef, CS_ADHOC | CS_LINKER_SIGNED);

can you update to the latest release of zld and see if you still have the issue? there still appear to be other differences in the codesign output, but at least it will fix the linker-signed flag and perhaps other things

karlpuusepp commented 2 years ago

@michaeleisel The latest release (1.3.3) still gives me the same ouput (code object not signed at all)

michaeleisel commented 2 years ago

OK, indeed I can reproduce it. When I use an arm64 phone as the target with new ld64, no ad-hoc signing. When I use an arm64 simulator with new ld64, I do see ad hoc signing. So in the zld/ld64 source code we have:

    // <rdar://problem/51911409> codesign all userland arm64 macOS binaries
    if ( dyldLoadsOutput() && (fArchitecture == CPU_TYPE_ARM64) && platforms().contains(ld::Platform::macOS) )
        fAdHocSign = true;

Indeed for macOS (but not simulator) arm64 binaries, zld works as we expect based on this code. It looks like that we should change it to do ad-hoc code signing by default when the platform is also the simulator, and not just for the mac. Seem good to everyone?

michaeleisel commented 2 years ago

Fixed in 786e7590f

michaeleisel commented 2 years ago

note that simulator builds with code-signing enabled will be slightly slower now, because it's doing both adhoc signing and normal signing. by the way, i wonder if adhoc code signing + manual entitlements injection for the simulator preserves functionality of things like app groups, meaning we can turn code signing off for any app for the simulator. do you know @keith ?

keith commented 2 years ago

The adhoc signing doesn't take entitlements into account at all, Xcode turns off ad-hoc signing instead I believe?

michaeleisel commented 2 years ago

good to hear that xcode turns off ad-hoc signing, so then there's no perf regression here. and looking over my steps in https://eisel.me/signing, it appears you just had to insert the entitlements at __TEXT,__entitlements, and i believe that fixed some (but not all) of the problems. so the question is if at least some of the other problems get fixed by now having adhoc signing.