JonathonReinhart / staticx

Create static executable from dynamic executable
https://staticx.readthedocs.io/
Other
345 stars 37 forks source link

Temporary extract directory permissions are too restrictive #286

Open haboustak opened 3 months ago

haboustak commented 3 months ago

I am trying to use staticx@0.14.1 with a pyinstaller@6.9.0 --onefile binary on Debian 12.5 and I'm receiving the following error:

$ sudo ./dist/script
Traceback (most recent call last):
  File "PyInstaller/loader/pyimod02_importers.py", line 187, in get_code
  File "PyInstaller/loader/pyimod01_archive.py", line 134, in extract
PermissionError: [Errno 13] Permission denied: '/tmp/staticx-FegNEo/script.onefile'

My script does a few unusual things that trigger this error.

  1. It must be run as root
  2. It switches the current user in order to access specific system resources (e.g. a database or a filesystem or a device)
  3. It lazily imports a Python module from the onefile package, such that the module is imported after the user switch.

The permissions on the temporary directory created by staticx are 700, but they should be 755.

$ ls -ald /tmp/staticx-FegNEo/
drwx------ 2 root root 4096 Aug  3 12:05 /tmp/staticx-FegNEo/

Minimal reproducing script is below.

import os
import sys

def main():
    if os.geteuid() != 0:
        print("ERROR: You must execute this script as root");
        sys.exit(1)

    # The uid/gid 1000 is the first non-system user on Debian 12
    # assumed to exist for this reproducer
    os.setgid(1000)
    os.setuid(1000)

    # lazy import after user switch triggers PermissionError
    import yaml
    print('ok')

if __name__ == '__main__':
    main()

I'm running staticx this way:

image: registry.gitlab.com/haboustak/glartifacts/build-env:1.3

aliases:
  onefile:
    script:
      - pyinstaller --onefile --distpath ./dist -n script.onefile ./script.py
      - staticx ./dist/script.onefile ./dist/script
haboustak commented 3 months ago

As I tried to fix this, I found that pyinstaller@6.9.0 --onefile has the same underlying issue.

$ sudo ./dist/script.onefile 
Traceback (most recent call last):
  File "script.py", line 17, in <module>
    main()
  File "script.py", line 12, in main
    import yaml
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
...
PermissionError: [Errno 13] Permission denied: '/tmp/_MEI2AXyUm/base_library.zip'
[310666] Failed to execute script 'script' due to unhandled exception!

$ ls -ald /tmp/_MEIhNeHmN/
drwx------ 3 root root 4096 Aug  3 12:32 /tmp/_MEIhNeHmN/
haboustak commented 3 months ago

As I tried to fix this, I found that pyinstaller@6.9.0 --onefile has the same underlying issue.

Upstream issue has been reported to PyInstaller. There's some discussion by the maintainer's on the best ways to fix it properly and safely (including how to avoid naming things too POSIX-ly, in consideration of Windows):

https://github.com/pyinstaller/pyinstaller/issues/8711

JonathonReinhart commented 3 months ago

I will probably prefer to go with whatever solution PyInstaller lands on.

kzmafia commented 2 weeks ago

So colo