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.