Skip to content

When EM_CACHE is overridden, Permission Denied crash occurs when installing system headers #24404

Closed
@Technius

Description

@Technius

When emscripten is installed to a location with read-only permissions (such as when installed with Nix) and the EM_CACHE environment variable is set to a folder with read-write-execute permissions, the emcc command still crashes when installing the system headers in the EM_CACHE.


Version of emscripten/emsdk:
Please include the output emcc -v here

emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 4.0.8-git
clang version 20.1.4
Target: wasm32-unknown-emscripten
Thread model: posix
InstalledDir: /nix/store/cf6j1f9f0z1syny3dgbickzc42zgcxhf-clang-20.1.4/bin

This bug does not occur with emcc 3.1.73

Failing command line in full:
If this is compile or link-time failure please include the full failing command
along with its entire output.

Log

Using an example.cpp with the contents:

#include <iostream>

int main(int argc, char** argv) {
    return 0;
}

Running emcc:

% EM_CACHE="$PWD"/emscriptencache emcc example.cpp
cache:INFO: generating system headers: sysroot_install.stamp... (this will be cached in "/private/tmp/example/emscriptencache/sysroot_install.stamp" for subsequent builds)
Traceback (most recent call last):
  File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/emcc.py", line 1597, in <module>
    sys.exit(main(sys.argv))
             ^^^^^^^^^^^^^^
  File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/emcc.py", line 1590, in main
    ret = run(args)
          ^^^^^^^^^
  File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/emcc.py", line 670, in run
    linker_args = phase_compile_inputs(options, state, newargs)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/emcc.py", line 919, in phase_compile_inputs
    system_libs.ensure_sysroot()
  File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/tools/system_libs.py", line 2519, in ensure_sysroot
    cache.get('sysroot_install.stamp', install_system_headers, what='system headers')
  File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/tools/cache.py", line 179, in get
    creator(str(cachename))
  File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/tools/system_libs.py", line 2486, in install_system_headers
    copytree_exist_ok(src, dest)
  File "/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/tools/system_libs.py", line 2463, in copytree_exist_ok
    shutil.copytree(src, dst, dirs_exist_ok=True)
  File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/shutil.py", line 600, in copytree
    return _copytree(entries=entries, src=src, dst=dst, symlinks=symlinks,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/v0vy1c59f0vf71h64caw17hzymvg0zms-python3-3.12.10/lib/python3.12/shutil.py", line 554, in _copytree
    raise Error(errors)
shutil.Error: [('/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/system/lib/compiler-rt/include/sanitizer', '/private/tmp/example/emscriptencache/sysroot/include/sanitizer', "[Errno 13] Permission denied: '/private/tmp/example/emscriptencache/sysroot/include/sanitizer'")]

Example of permissions in system installation (/nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/system/lib/compiler-rt/include/sanitizer):

total 692
dr-xr-xr-x 18 root nixbld    576 Dec 31  1969 .
dr-xr-xr-x  3 root nixbld     96 Dec 31  1969 ..
-r--r--r--  1 root nixbld   4973 Dec 31  1969 allocator_interface.h
-r--r--r--  1 root nixbld  13654 Dec 31  1969 asan_interface.h
-r--r--r--  1 root nixbld  20763 Dec 31  1969 common_interface_defs.h
-r--r--r--  1 root nixbld   1133 Dec 31  1969 coverage_interface.h
-r--r--r--  1 root nixbld  10102 Dec 31  1969 dfsan_interface.h
-r--r--r--  1 root nixbld   5043 Dec 31  1969 hwasan_interface.h
-r--r--r--  1 root nixbld 219473 Dec 31  1969 linux_syscall_hooks.h
-r--r--r--  1 root nixbld   3993 Dec 31  1969 lsan_interface.h
-r--r--r--  1 root nixbld   2648 Dec 31  1969 memprof_interface.h
-r--r--r--  1 root nixbld   5992 Dec 31  1969 msan_interface.h
-r--r--r--  1 root nixbld 355693 Dec 31  1969 netbsd_syscall_hooks.h
-r--r--r--  1 root nixbld   2835 Dec 31  1969 nsan_interface.h
-r--r--r--  1 root nixbld   1513 Dec 31  1969 scudo_interface.h
-r--r--r--  1 root nixbld  14952 Dec 31  1969 tsan_interface.h
-r--r--r--  1 root nixbld  11232 Dec 31  1969 tsan_interface_atomic.h
-r--r--r--  1 root nixbld   1044 Dec 31  1969 ubsan_interface.h

Note that the corresponding folder in EM_CACHE -- /private/tmp/example/emscriptencache/sysroot/include/sanitizer -- is not actually created.

The files that do get installed have the permission bits copied from the system installation:

ls -la emscriptencache/sysroot/include/fakesdl | head -n 5
total 212
dr-xr-xr-x 55 bryantan wheel 1760 Dec 31  1969 .
dr-xr-xr-x 21 bryantan wheel  672 Dec 31  1969 ..
-r--r--r--  1 bryantan wheel   72 Dec 31  1969 SDL.h
-r--r--r--  1 bryantan wheel   72 Dec 31  1969 SDL_assert.h

A workaround for this bug is to copy the system installation of the cache manually and change the permissions bits before running emcc.

EM_CACHE="$PWD"/emscriptencache
cp -r /nix/store/bzq9l9651iqfk63glxdd3z7lxl10lilz-emscripten-4.0.8/share/emscripten/cache "$EM_CACHE"
chmod u+rwX -R "$EM_CACHE"
emcc example.cpp

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions