diff options
author | Theodore Ni <3806110+tjni@users.noreply.github.com> | 2022-08-20 13:01:12 -0700 |
---|---|---|
committer | Theodore Ni <3806110+tjni@users.noreply.github.com> | 2022-11-20 16:16:07 -0800 |
commit | 4fc97dce3cfe544151c49e072180863d586084d4 (patch) | |
tree | f0510fadf737141c8b285e7dd30fc5643f9d3045 /pkgs/development | |
parent | 231da8ef225fac545de2a1891e8f96c21ccbad35 (diff) |
python310Packages.cffi: patch closures to work on M1 machines
Trusts the libffi library inside of nixpkgs on Apple devices. When Apple's fork of libffi is not detected, cffi assumes that libffi uses a strategy for creating closures (i.e. callbacks) that is in certain cases susceptible to a security exploit. Based on some analysis I did: https://groups.google.com/g/python-cffi/c/xU0Usa8dvhk I believe that libffi already contains the code from Apple's fork that is deemed safe to trust in cffi. It uses a more sophisticated strategy for creating trampolines to support closures that works on Apple Silicon, while the simple approach that cffi falls back on does not, so this patch enables code that uses closures on M1 Macs again. Notably, pyOpenSSL is impacted and will be fixed by this, reported in https://github.com/pyca/pyopenssl/issues/873 Note that libffi closures still will not work on signed apps without the com.apple.security.cs.allow-unsigned-executable-memory entitlement while https://github.com/libffi/libffi/pull/621 is still open (which I haven't tested but is my best guess from reading). I am hopeful that all of these changes will be upstreamed back into cffi and libffi, and that this comment provides enough breadcrumbs for future maintainers to track and clean this up.
Diffstat (limited to 'pkgs/development')
3 files changed, 90 insertions, 5 deletions
diff --git a/pkgs/development/python-modules/cffi/darwin-use-libffi-closures.diff b/pkgs/development/python-modules/cffi/darwin-use-libffi-closures.diff new file mode 100644 index 0000000000000..c48c8090dd461 --- /dev/null +++ b/pkgs/development/python-modules/cffi/darwin-use-libffi-closures.diff @@ -0,0 +1,21 @@ +diff -r bac92fcfe4d7 c/_cffi_backend.c +--- a/c/_cffi_backend.c Mon Jul 18 15:58:34 2022 +0200 ++++ b/c/_cffi_backend.c Sat Aug 20 12:38:31 2022 -0700 +@@ -96,7 +96,7 @@ + # define CFFI_CHECK_FFI_PREP_CIF_VAR 0 + # define CFFI_CHECK_FFI_PREP_CIF_VAR_MAYBE 0 + +-#elif defined(__APPLE__) && defined(FFI_AVAILABLE_APPLE) ++#elif defined(__APPLE__) + + # define CFFI_CHECK_FFI_CLOSURE_ALLOC __builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *) + # define CFFI_CHECK_FFI_CLOSURE_ALLOC_MAYBE 1 +@@ -6413,7 +6413,7 @@ + else + #endif + { +-#if defined(__APPLE__) && defined(FFI_AVAILABLE_APPLE) && !FFI_LEGACY_CLOSURE_API ++#if defined(__APPLE__) && !FFI_LEGACY_CLOSURE_API + PyErr_Format(PyExc_SystemError, "ffi_prep_closure_loc() is missing"); + goto error; + #else diff --git a/pkgs/development/python-modules/cffi/default.nix b/pkgs/development/python-modules/cffi/default.nix index 66b315f14ab0c..aa1df2e51673b 100644 --- a/pkgs/development/python-modules/cffi/default.nix +++ b/pkgs/development/python-modules/cffi/default.nix @@ -1,5 +1,12 @@ -{ lib, stdenv, buildPythonPackage, isPyPy, fetchPypi, pytestCheckHook, - libffi, pkg-config, pycparser +{ lib +, stdenv +, buildPythonPackage +, isPyPy +, fetchPypi +, pytestCheckHook +, libffi +, pkg-config +, pycparser }: if isPyPy then null else buildPythonPackage rec { @@ -11,6 +18,20 @@ if isPyPy then null else buildPythonPackage rec { sha256 = "sha256-1AC/uaN7E1ElPLQCZxzqfom97MKU6AFqcH9tHYrJNPk="; }; + patches = [ + # + # Trusts the libffi library inside of nixpkgs on Apple devices. + # + # Based on some analysis I did: + # + # https://groups.google.com/g/python-cffi/c/xU0Usa8dvhk + # + # I believe that libffi already contains the code from Apple's fork that is + # deemed safe to trust in cffi. + # + ./darwin-use-libffi-closures.diff + ]; + buildInputs = [ libffi ]; nativeBuildInputs = [ pkg-config ]; @@ -29,9 +50,7 @@ if isPyPy then null else buildPythonPackage rec { NIX_CFLAGS_COMPILE = lib.optionalString stdenv.cc.isClang "-Wno-unused-command-line-argument -Wno-unreachable-code -Wno-c++11-narrowing"; - # Lots of tests fail on aarch64-darwin due to "Cannot allocate write+execute memory": - # * https://cffi.readthedocs.io/en/latest/using.html#callbacks - doCheck = !stdenv.hostPlatform.isMusl && !(stdenv.isDarwin && stdenv.isAarch64); + doCheck = !stdenv.hostPlatform.isMusl; checkInputs = [ pytestCheckHook ]; diff --git a/pkgs/development/python2-modules/cffi/default.nix b/pkgs/development/python2-modules/cffi/default.nix new file mode 100644 index 0000000000000..adeda6e90d229 --- /dev/null +++ b/pkgs/development/python2-modules/cffi/default.nix @@ -0,0 +1,45 @@ +{ lib, stdenv, cffi }: + +if cffi == null then null else cffi.overridePythonAttrs { + disabledTests = lib.optionals stdenv.isDarwin [ + # cannot load library 'c' + "test_FILE" + "test_FILE_object" + "test_FILE_only_for_FILE_arg" + "test_load_and_call_function" + "test_load_library" + + # cannot load library 'dl' + "test_dlopen_handle" + + # cannot load library 'm' + "test_dir_on_dlopen_lib" + "test_dlclose" + "test_dlopen" + "test_dlopen_constant" + "test_dlopen_flags" + "test_function_typedef" + "test_line_continuation_in_defines" + "test_missing_function" + "test_remove_comments" + "test_remove_line_continuation_comments" + "test_simple" + "test_sin" + "test_sinf" + "test_stdcall_only_on_windows" + "test_wraps_from_stdlib" + + # MemoryError + "test_callback_as_function_argument" + "test_callback_crash" + "test_callback_decorator" + "test_callback_large_struct" + "test_callback_returning_void" + "test_cast_functionptr_and_int" + "test_function_pointer" + "test_functionptr_intptr_return" + "test_functionptr_simple" + "test_functionptr_void_return" + "test_functionptr_voidptr_return" + ]; +} |