Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PyInstaller 4.5.1 "codesign failure!" on macos #6167

Closed
arossert opened this issue Aug 26, 2021 · 22 comments · Fixed by #6188
Closed

PyInstaller 4.5.1 "codesign failure!" on macos #6167

arossert opened this issue Aug 26, 2021 · 22 comments · Fixed by #6188

Comments

@arossert
Copy link
Contributor

I'm trying to build my application on macOS and I'm getting this error with the latest PyInstaller 4.5.1, it is working on PyInstaller 4.3

[2021-08-26T07:28:02.721Z] 12064 WARNING: codesign command (['codesign', '-s', '-', '--force', '--all-architectures', '--timestamp', '/Users/safebreach/Library/Application Support/pyinstaller/bincache00_py37_64bit/x86_64/adhoc/no-entitlements/libintl.8.dylib']) failed with error code 1!
[2021-08-26T07:28:02.721Z] stdout: ''
[2021-08-26T07:28:02.721Z] stderr: '/Users/safebreach/Library/Application Support/pyinstaller/bincache00_py37_64bit/x86_64/adhoc/no-entitlements/libintl.8.dylib: invalid or unsupported format for signature\n'
[2021-08-26T07:28:02.721Z] Traceback (most recent call last):
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/bin/pyinstaller", line 8, in <module>
[2021-08-26T07:28:02.721Z]     sys.exit(run())
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/__main__.py", line 126, in run
[2021-08-26T07:28:02.721Z]     run_build(pyi_config, spec_file, **vars(args))
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/__main__.py", line 65, in run_build
[2021-08-26T07:28:02.721Z]     PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 815, in main
[2021-08-26T07:28:02.721Z]     build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 762, in build
[2021-08-26T07:28:02.721Z]     exec(code, spec_namespace)
[2021-08-26T07:28:02.721Z]   File "cicd/connectivity_check.spec", line 55, in <module>
[2021-08-26T07:28:02.721Z]     console=True
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/building/api.py", line 515, in __init__
[2021-08-26T07:28:02.721Z]     entitlements_file=self.entitlements_file
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/building/api.py", line 208, in __init__
[2021-08-26T07:28:02.721Z]     self.__postinit__()
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/building/datastruct.py", line 159, in __postinit__
[2021-08-26T07:28:02.721Z]     self.assemble()
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/building/api.py", line 280, in assemble
[2021-08-26T07:28:02.721Z]     entitlements_file=self.entitlements_file)
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/building/utils.py", line 391, in checkCache
[2021-08-26T07:28:02.721Z]     osxutils.sign_binary(cachedfile, codesign_identity, entitlements_file)
[2021-08-26T07:28:02.721Z]   File "/Volumes/workspace/workspace/ConnectivityCheck_develop/connectivity_check_venv/lib/python3.7/site-packages/PyInstaller/utils/osx.py", line 383, in sign_binary
[2021-08-26T07:28:02.721Z]     raise SystemError("codesign failure!")

Is there a way to work around it?

PyInstaller: 4.5.1
Python: 3.7.9
OS: macOS

@arossert arossert added the triage Please triage and relabel this issue label Aug 26, 2021
@rokm
Copy link
Member

rokm commented Aug 26, 2021

[2021-08-26T07:28:02.721Z] stderr: '/Users/safebreach/Library/Application Support/pyinstaller/bincache00_py37_64bit/x86_64/adhoc/no-entitlements/libintl.8.dylib: invalid or unsupported format for signature\n'

Can you figure out where the offending libintl.8.dylib came from?

Is there a way to work around it?

I suppose if you don't care about binaries not being code signed (even ad-hoc), you could comment the raise of SystemError in your local PyInstaller version ("PyInstaller/utils/osx.py", line 383, in sign_binary), so the error becomes non-fatal.

@arossert
Copy link
Contributor Author

I have no idea what is this file, I have searched for it in the machine and this is what I have found

Build-Simulator-2:ConnectivityCheck_develop safebreach$ find / -name libintl.8.dylib 2>/dev/null
/usr/local/lib/libintl.8.dylib
/usr/local/Cellar/gettext/0.21/lib/libintl.8.dylib
/Users/safebreach/Library/Application Support/pyinstaller/bincache00_py37_64bit/libintl.8.dylib
/Applications/Wireshark.app/Contents/Frameworks/libintl.8.dylib

I really don't want to start editing the code to disable the codesign, why in 4.3 everything is working?

@rokm
Copy link
Member

rokm commented Aug 26, 2021

I really don't want to start editing the code to disable the codesign, why in 4.3 everything is working?

Because in 4.3, we do not (re-)sign the binaries we collect.

@rokm
Copy link
Member

rokm commented Aug 26, 2021

I have no idea what is this file.

Can you attach the Analysis-00.toc file from your build/<name> directory?

Also, what macOS version are you using?

@lachlancresswell
Copy link

lachlancresswell commented Aug 26, 2021

My build passes on my MacOS 11.5.2 machine but fails on my OSX 10.13.6 VM:

2444 WARNING: codesign command (['codesign', '-s', '-', '--force', '--all-architectures', '--timestamp', '/Users/lachlan/Library/Application Support/pyinstaller/bincache00_py39_64bit/x86_64/adhoc/no-entitlements/libreadline.8.dylib']) failed with error code 1!
stdout: ''
stderr: '/Users/lachlan/Library/Application Support/pyinstaller/bincache00_py39_64bit/x86_64/adhoc/no-entitlements/libreadline.8.dylib: invalid or unsupported format for signature\n'
Traceback (most recent call last):
  File "/Users/lachlan/autor1/env/bin/pyinstaller", line 8, in <module>
    sys.exit(run())
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/__main__.py", line 126, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/__main__.py", line 65, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/building/build_main.py", line 815, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/building/build_main.py", line 762, in build
    exec(code, spec_namespace)
  File "/Users/lachlan/autor1/autor1.spec", line 23, in <module>
    exe = EXE(pyz,
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/building/api.py", line 509, in __init__
    self.pkg = PKG(self.toc, cdict=kwargs.get('cdict', None),
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/building/api.py", line 208, in __init__
    self.__postinit__()
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/building/datastruct.py", line 159, in __postinit__
    self.assemble()
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/building/api.py", line 274, in assemble
    fnm = checkCache(fnm, strip=self.strip_binaries,
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/building/utils.py", line 391, in checkCache
    osxutils.sign_binary(cachedfile, codesign_identity, entitlements_file)
  File "/Users/lachlan/autor1/env/lib/python3.9/site-packages/PyInstaller/utils/osx.py", line 383, in sign_binary
    raise SystemError("codesign failure!")
SystemError: codesign failure

And the same failure but for pyinstaller/bincache00_py37_64bit/x86_64/adhoc/no-entitlements/lib-dynload/unicodedata.cpython-37m-darwin.so under the current default (OSX 10.13.6) Travis environment.

Swapping from ad-hoc signing to self-signed passed as expected.

@arossert
Copy link
Contributor Author

@lachyc How can I use "self-signed" instead of "ad-hoc" ?

@lachlancresswell
Copy link

lachlancresswell commented Aug 26, 2021

@lachyc How can I use "self-signed" instead of "ad-hoc" ?

@arossert

  1. Open Keychain Access

  2. Go to the menu at the top of the screen and select Keychain Access > Certificate Assistant > Create a Certificate

  3. In the window that appears change Certificate Type to Code Signing , select Create and note the name of the certificate

  4. Build your pyinstaller source with the --codesign-identity <name> flag where <name> is the name of the certificate you created in step 3

@rokm
Copy link
Member

rokm commented Aug 26, 2021

My build passes on my MacOS 11.5.2 machine but fails on my OSX 10.13.6 VM:

This does look like an issue with codesign on 10.13 - sometimes it seems to fail to properly remove the signature from a file, and then subsequent attempt to re-sign it fails... and this seems to happen only sometimes, even when given a fresh copy of the same source file (e.g., lib-dynload/zlib.cpython-38-darwin.so).

Swapping from ad-hoc signing to self-signed passed as expected.

Does the self-signed app work correctly, though? If signing identity is provided, we turn on hardened runtime, and according to my tests, that did not work with self-signed certificate...

@lachlancresswell
Copy link

lachlancresswell commented Aug 26, 2021

Swapping from ad-hoc signing to self-signed passed as expected.

Does the self-signed app work correctly, though? If signing identity is provided, we turn on hardened runtime, and according to my tests, that did not work with self-signed certificate...

Running pyinstaller 4.5.1 with a self-signed certificate on 10.13 generates an app that runs on both 10.13 and 11.5.2 for me.

Edit: Building on 11.5.2 with a self-signed cert works too.

I am generating a single binary rather than a .app bundle in case that makes any difference!

@rokm rokm removed the triage Please triage and relabel this issue label Aug 29, 2021
@rokm
Copy link
Member

rokm commented Aug 29, 2021

Hmm, interesting. Thanks for the input.

On my test High Sierra system, ad-hoc or self-signed makes no difference; the re-signing fails in both cases. Actually, I suspect that it is the removal of the signature (which we perform prior to other modifications) that somehow corrupts the file with that version of codesign. (And then attempt to sign it back fails; this happens even if signature removal and re-signing are attempted manually, without pyinstaller-specific processing in between).

Running pyinstaller 4.5.1 with a self-signed certificate on 10.13 generates an app that runs on both 10.13 and 11.5.2 for me.

Edit: Building on 11.5.2 with a self-signed cert works too.

I am generating a single binary rather than a .app bundle in case that makes any difference!

On my test Big Sur system, a onedir console application, signed with self-signed certificate, fails to launch. But I remember that I initially overlooked the problem as well, because I had previously disabled gatekeeper via spctl --master-disable. Have you done so on your system as well?

@rokm
Copy link
Member

rokm commented Aug 29, 2021

But back to the original issue, if it is the signature removal that codesign on High Sierra cannot handle properly, we could try skipping that.

We definitely need to remove signature (if present) from the bootloader due to the way we "hide" the appended archive inside the executable. But for collected binaries, perhaps just forcing a re-sign after modifying headers, without prior removal of signature, might do the trick as well.

@arossert and @lachyc, can you try patching your pyinstaller installations on High Sierra to comment out this line:

osxutils.remove_signature_from_binary(cachedfile)

It seems to fix the codesign errors on my test system (with ad-hoc signing), and the resulting signatures on collected binaries as well as the whole frozen application seem to be OK.

@arossert
Copy link
Contributor Author

@rokm After commenting out the line from my env this is what I'm getting:

35075 INFO: Fixing EXE for code signing /Volumes/workspace/workspace/UpdateClient_master/build/update-client/updater
Traceback (most recent call last):
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/bin/pyinstaller", line 8, in <module>
    sys.exit(run())
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/__main__.py", line 126, in run
    run_build(pyi_config, spec_file, **vars(args))
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/__main__.py", line 65, in run_build
    PyInstaller.building.build_main.main(pyi_config, spec_file, **kwargs)
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 815, in main
    build(specfile, kw.get('distpath'), kw.get('workpath'), kw.get('clean_build'))
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/building/build_main.py", line 762, in build
    exec(code, spec_namespace)
  File "cicd/update-client.spec", line 66, in <module>
    icon='../icon.ico'
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/building/api.py", line 524, in __init__
    self.__postinit__()
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/building/datastruct.py", line 159, in __postinit__
    self.assemble()
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/building/api.py", line 761, in assemble
    osxutils.fix_exe_for_code_signing(self.name)
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/utils/osx.py", line 212, in fix_exe_for_code_signing
    symtab_sec.stroff + symtab_sec.strsize, "Sanity check failed!"
AssertionError: Sanity check failed!

@rokm
Copy link
Member

rokm commented Aug 30, 2021

Hmmm, odd. Disabling signature removal for collected binaries should not have any effect on the generated frozen executable itself... Unless, is this a onefile build? In that case, binaries would have been processed before the executable, which means that this is an additional error...

Can you try the following:

  • create a copy of pyinstaller's bootloader (/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/bootloader/Darwin-64bi/run) to your current working directory
  • open python with your environment activated, and run:
from PyInstaller.utils.osx import fix_exe_for_code_signing, binary_to_target_arch
binary_to_target_arch('./run', 'x86_64')
fix_exe_for_code_signing('./run')
  • remove the copy of run in current working directory, and create another copy. Then run in python:
from PyInstaller.utils.osx import fix_exe_for_code_signing, binary_to_target_arch, remove_signature_from_binary
binary_to_target_arch('./run', 'x86_64')
remove_signature_from_binary('./run')
fix_exe_for_code_signing('./run')

Do either of the two attempts generate the sanity check error?

@arossert
Copy link
Contributor Author

I'm using onedir and not onefile

This is the first command output:

(updater_venv) Build-Simulator-2:UpdateClient_master safebreach$ python
Python 3.7.9 (default, Sep  8 2020, 10:54:43)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyInstaller.utils.osx import fix_exe_for_code_signing, binary_to_target_arch
>>> binary_to_target_arch('./run', 'x86_64')
>>> fix_exe_for_code_signing('./run')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/utils/osx.py", line 195, in fix_exe_for_code_signing
    assert len(sign_sec) == 0, "Executable contains code signature!"
AssertionError: Executable contains code signature!
>>>

And the second one:

(updater_venv) Build-Simulator-2:UpdateClient_master safebreach$ python
Python 3.7.9 (default, Sep  8 2020, 10:54:43)
[Clang 9.0.0 (clang-900.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyInstaller.utils.osx import fix_exe_for_code_signing, binary_to_target_arch, remove_signature_from_binary
>>> binary_to_target_arch('./run', 'x86_64')
>>> remove_signature_from_binary('./run')
>>> fix_exe_for_code_signing('./run')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Volumes/workspace/workspace/UpdateClient_master/updater_venv/lib/python3.7/site-packages/PyInstaller/utils/osx.py", line 212, in fix_exe_for_code_signing
    symtab_sec.stroff + symtab_sec.strsize, "Sanity check failed!"
AssertionError: Sanity check failed!
>>>

@rokm
Copy link
Member

rokm commented Aug 30, 2021

This looks like the codesign failing to properly remove the signature from the bootloader. Can I ask you to:

  • make a copy of run to local directory again
  • process it with binary_to_target_arch('./run', 'x86_64')
  • create a copy of processed file, e.g., run_nosig
  • process the created copy with remove_signature_from_binary('./run_nosig')

Then upload both run and run_nosig files somewhere, so I can take a look at them? (On my test system, this removal seems to work without issues...)


But you could probably work around this issue by not having a signed bootloader in the first place. I.e, by downloading the sdist (or creating a git checkout for 4.5.1 tag), rebuilding the bootloader locally (cd pyinstaller-4.5.1/bootloader; python waf all), patching the pyinstaller-4.5.1/PyInstaller/building/utils.py, and then installing from unpacked & modified source (pip install ./pyinstaller-4.5.1).

@arossert
Copy link
Contributor Author

Here are the files:

Archive.zip

@rokm
Copy link
Member

rokm commented Aug 30, 2021

Thanks for the files.

The sanity check fails because after codesign removes the signature, the __LINKEDIT segment's size ends up pointing 8 bytes past the end of file, while SYMTAB correctly points at the end of file. So that's another bug in codesign on 10.13. But I suppose we could work around such oddities by directly computing the new segment and section size (instead of first estimating old file size from declared segment size, and then the delta based on the new size), which would swallow up such inconsistencies.

@rokm
Copy link
Member

rokm commented Aug 30, 2021

Can you check if fixes in these branches (the first is based on develop, the other on v4) solve the problems on your 10.13?

https://github.com/rokm/pyinstaller/tree/robustify-macos-assembly-pipeline
https://github.com/rokm/pyinstaller/tree/robustify-macos-assembly-pipeline-v4

@arossert
Copy link
Contributor Author

arossert commented Sep 4, 2021

@rokm I have tried the first branch
https://github.com/rokm/pyinstaller/tree/robustify-macos-assembly-pipeline - 5.0.dev0
https://github.com/rokm/pyinstaller/tree/robustify-macos-assembly-pipeline-v4 - 4.6.dev0
and it seems to work on both of them.

@section83
Copy link

I've tested the 5.0.dev0 version of PyInstaller on a Mac Mini running macOS 10.13.6 with Python3.9.7 installed.

The resulting single folder version is over 2.05GB. This is primary because of this file: binascii.cpython-39-darwin.so which is 2.03GB. It runs reasonably fast.

The single file form is only 12.3MB but runs very, very slowly e.g. 35 seconds to get version on the Python app.

Is that normal ?

Is it due to Python3.9 or some other factor ?

@rokm
Copy link
Member

rokm commented Sep 30, 2021

Is that normal ?

Is it due to Python3.9 or some other factor ?

Can you compare the sizes of binary extensions (e.g., binascii.cpython-39-darwin.so) in the python installation itself vs. those that end up collected in onedir build? I've seen codesign on 10.13 drastically increase size of a file (probably due to a bug) - although that seemed to occur only when removing the signature (which 5.0dev should have disabled. But perhaps it also happens during re-signing?

It could be that such corrupted files end up compressing very well, and that's where the difference between onedir and onefile is coming from.

@section83
Copy link

Can you compare the sizes of binary extensions (e.g., binascii.cpython-39-darwin.so) in the python installation itself vs. those that end up collected in onedir build?

In the Python framework "lib-dynload" folder, that file is 53KB. In the onedir list it's 2.03GB. I've checked 7 other library files – two had different files sizes: _lzma.cpython-39-darwin.so which is 258,096 bytes in the installed framework and 257,264 bytes in the onedir libs. "_ssl.cpython-39-darwin.so" is 187,504 bytes and 186,672 bytes respectively.

Without the binascci file, the entire folder in the onedir lib-dynload is 6,764,064 bytes. The installed framework lib-dynload folder is 8,063,344 bytes.

BTW,

The single file form is only 12.3MB but runs very, very slowly e.g. 35 seconds to get version on the Python app.

The singlefile build on Catalina is only 7.7MB.

Cheers.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants