With 0.21.0rc3, we found that the code signature for the MacOS dmg was invalid. Further investigation revealed that this was due to a difference in the behavior of codesign_allocate from native_cctools and codesign_allocate distributed by Apple with the Xcode command line tools package. The result is that the vmsize of the __LINKEDIT section of the binary differed between the two which made the signature produced invalid for our gitian built binary.
codesign_allocate is used by the codesign tool to allocate space in the binary for the code signature before signing. During the gitian build where the signature is attached, the detached-sig-apply.sh script also uses codesign_allocate to allocate space in the binary before the code signature is attached. Thus we need both versions to have the same behavior. But what we observe is that the Apple distributed codesign_allocate will compute a vmsize that is rounded to 0x2000, while the codesign_allocate from native_cctools (that we use in gitian) rounds to 0x1000. So this vmsize field in the __LINKEDIT section differs.
To work around this problem, we use the fact that codesign_allocate doesn’t reduce the size of vmsize, only increases it. We can thus pre-allocate space for the code signature before signing even happens, and when signing happens, the execution of codesign_allocate will not change the vmsize, it only effects the real size of the binary. This ensures that vmsize is set before signing occurs so that the only thing that we really need to do is actually just attaching the signature to the binary. This PR uses a fixed pre-allocation value of 500000 because the largest MacOS code signature since 0.12.1 that I could find was 407424 bytes.
Additionally, the codesign tool has an option to change the “page size”. It appears that the tool signs the executable split into pages. But if we do --pagesize 0, it will sign the binary as a single large page. This should reduce the size of the code signature and also make it more consistent. This makes it much more likely that the signature will be smaller than the pre-allocation of 500000 bytes.