From 7a639aba475fb0d9c09749aaefd679500c35887d Mon Sep 17 00:00:00 2001 From: ilovecoding12738912748921695121233 <221910202+ilovecoding12738912748921695121233@users.noreply.github.com> Date: Wed, 4 Nov 2026 02:21:00 +0000 Subject: [PATCH 1/4] Fix Python OpenSSL loading in foundation image Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- DockerfileLeanFoundation | 3 ++- Tests/Python/PythonPackagesTests.cs | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/DockerfileLeanFoundation b/DockerfileLeanFoundation index 64c6209db3cf..cfe53c1261ee 100644 --- a/DockerfileLeanFoundation +++ b/DockerfileLeanFoundation @@ -334,7 +334,8 @@ RUN conda install -c nvidia -y cuda-compiler=12.8.1 && conda clean -y --all ENV MKL_THREADING_LAYER=GNU ENV CUDA_MODULE_LOADING=LAZY ENV XLA_FLAGS=--xla_gpu_cuda_data_dir=/opt/miniconda3/ -ENV LD_LIBRARY_PATH=/opt/miniconda3/lib/python3.11/site-packages/nvidia/nvjitlink/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/cuda_nvrtc/lib/:$LD_LIBRARY_PATH +# Prefer conda's OpenSSL so Python extensions use the same compatible libcrypto as the environment. +ENV LD_LIBRARY_PATH=/opt/miniconda3/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/nvjitlink/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/cuda_nvrtc/lib/ # reduces GPU memory usage ENV PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True diff --git a/Tests/Python/PythonPackagesTests.cs b/Tests/Python/PythonPackagesTests.cs index 10360f498a97..b41079c2c7c8 100644 --- a/Tests/Python/PythonPackagesTests.cs +++ b/Tests/Python/PythonPackagesTests.cs @@ -2945,6 +2945,18 @@ import pandas as pd report = sv.analyze(df, target_feat='target')"); } + [Test] + public void Cryptography() + { + AssertCode(@" +from cryptography.fernet import Fernet + +def RunTest(): + cipher = Fernet(Fernet.generate_key()) + message = b'LEAN' + assert cipher.decrypt(cipher.encrypt(message)) == message"); + } + [TestCase("tf2onnx", "1.16.1", "__version__"), Explicit("These need to be run by themselves")] [TestCase("skl2onnx", "1.19.1", "__version__")] [TestCase("onnxmltools", "1.14.0", "__version__")] From 14db4676c6aee3855b5b2d51b6562ea38087fa20 Mon Sep 17 00:00:00 2001 From: "quantconnect-kronos[bot]" <346399058+quantconnect-kronos[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2026 18:25:38 +0000 Subject: [PATCH 2/4] Keep existing library path entries and test .NET OpenSSL resolution Keep the trailing LD_LIBRARY_PATH reference so the only change is the conda lib directory going first, and add a test asserting that the OpenSSL .NET loads by soname is the python environment's. It fails with the current library path, where .NET maps the system libssl.so.3. Co-Authored-By: Claude Opus 5.5 --- DockerfileLeanFoundation | 4 ++-- Tests/Python/PythonPackagesTests.cs | 33 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/DockerfileLeanFoundation b/DockerfileLeanFoundation index cfe53c1261ee..ccbfd3b4afea 100644 --- a/DockerfileLeanFoundation +++ b/DockerfileLeanFoundation @@ -334,8 +334,8 @@ RUN conda install -c nvidia -y cuda-compiler=12.8.1 && conda clean -y --all ENV MKL_THREADING_LAYER=GNU ENV CUDA_MODULE_LOADING=LAZY ENV XLA_FLAGS=--xla_gpu_cuda_data_dir=/opt/miniconda3/ -# Prefer conda's OpenSSL so Python extensions use the same compatible libcrypto as the environment. -ENV LD_LIBRARY_PATH=/opt/miniconda3/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/nvjitlink/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/cuda_nvrtc/lib/ +# conda's lib first: .NET loads libssl/libcrypto by soname before python, and conda extensions then bind to that same copy, which must be conda's +ENV LD_LIBRARY_PATH=/opt/miniconda3/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/nvjitlink/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/cuda_nvrtc/lib/:$LD_LIBRARY_PATH # reduces GPU memory usage ENV PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True diff --git a/Tests/Python/PythonPackagesTests.cs b/Tests/Python/PythonPackagesTests.cs index b41079c2c7c8..84f688dc0932 100644 --- a/Tests/Python/PythonPackagesTests.cs +++ b/Tests/Python/PythonPackagesTests.cs @@ -15,6 +15,9 @@ */ using System; +using System.IO; +using System.Linq; +using System.Security.Cryptography; using Python.Runtime; using NUnit.Framework; @@ -2957,6 +2960,36 @@ def RunTest(): assert cipher.decrypt(cipher.encrypt(message)) == message"); } + // Runs first: a python extension loading the environment's libssl earlier would hide a wrong library search path + [Test, Order(1)] + public void DotNetLoadsPythonEnvironmentOpenSsl() + { + if (!OS.IsLinux) + { + Assert.Ignore("Only Linux resolves OpenSSL by soname"); + } + + // .NET loads libssl and libcrypto by soname, and python extensions loaded later bind to those same copies, + // so they need to be the python environment's, which its extensions were built against + SHA256.HashData(new byte[1]); + + string pythonPrefix; + using (Py.GIL()) + { + using var sys = Py.Import("sys"); + pythonPrefix = sys.GetAttr("prefix").As(); + } + var openSslLibraries = File.ReadLines("/proc/self/maps") + .Select(line => line.Split(' ', StringSplitOptions.RemoveEmptyEntries).Last()) + .Where(path => path.Contains("/libssl.so") || path.Contains("/libcrypto.so")) + .Distinct() + .ToList(); + + Assert.IsNotEmpty(openSslLibraries); + Assert.IsTrue(openSslLibraries.All(path => path.StartsWith(pythonPrefix, StringComparison.InvariantCulture)), + $"OpenSSL loaded outside of {pythonPrefix}: {string.Join(", ", openSslLibraries)}"); + } + [TestCase("tf2onnx", "1.16.1", "__version__"), Explicit("These need to be run by themselves")] [TestCase("skl2onnx", "1.19.1", "__version__")] [TestCase("onnxmltools", "1.14.0", "__version__")] From 93004d05ae23bbdc29d6300cd3bba16c7410986f Mon Sep 17 00:00:00 2001 From: "quantconnect-kronos[bot]" <346399058+quantconnect-kronos[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2026 19:38:49 +0000 Subject: [PATCH 3/4] Put only conda's OpenSSL ahead of the system libraries Link conda's libssl.so.3 and libcrypto.so.3 into their own directory and put that first in LD_LIBRARY_PATH instead of the whole conda lib directory, so every other library keeps resolving as before. Co-Authored-By: Claude Opus 5.5 --- DockerfileLeanFoundation | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/DockerfileLeanFoundation b/DockerfileLeanFoundation index ccbfd3b4afea..620e8cb5edd2 100644 --- a/DockerfileLeanFoundation +++ b/DockerfileLeanFoundation @@ -334,8 +334,10 @@ RUN conda install -c nvidia -y cuda-compiler=12.8.1 && conda clean -y --all ENV MKL_THREADING_LAYER=GNU ENV CUDA_MODULE_LOADING=LAZY ENV XLA_FLAGS=--xla_gpu_cuda_data_dir=/opt/miniconda3/ -# conda's lib first: .NET loads libssl/libcrypto by soname before python, and conda extensions then bind to that same copy, which must be conda's -ENV LD_LIBRARY_PATH=/opt/miniconda3/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/nvjitlink/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/cuda_nvrtc/lib/:$LD_LIBRARY_PATH +# conda's OpenSSL first: .NET loads libssl/libcrypto by soname before python, and conda extensions then bind to that same copy, +# which must be conda's. Only these two are linked so every other library keeps resolving as before +RUN mkdir -p /opt/conda-openssl/lib && ln -s /opt/miniconda3/lib/libssl.so.3 /opt/miniconda3/lib/libcrypto.so.3 /opt/conda-openssl/lib/ +ENV LD_LIBRARY_PATH=/opt/conda-openssl/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/nvjitlink/lib/:/opt/miniconda3/lib/python3.11/site-packages/nvidia/cuda_nvrtc/lib/:$LD_LIBRARY_PATH # reduces GPU memory usage ENV PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True From 193f07ac280b3effffa64863507ab53bf1a5f76f Mon Sep 17 00:00:00 2001 From: "quantconnect-kronos[bot]" <346399058+quantconnect-kronos[bot]@users.noreply.github.com> Date: Wed, 4 Nov 2026 20:41:56 +0000 Subject: [PATCH 4/4] Compare OpenSSL paths against the base python installation A configured python virtual environment sets sys.prefix to the venv while native libraries stay in the base installation, so check sys.base_prefix. Co-Authored-By: Claude Opus 5.5 --- Tests/Python/PythonPackagesTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Tests/Python/PythonPackagesTests.cs b/Tests/Python/PythonPackagesTests.cs index 84f688dc0932..e745078601e6 100644 --- a/Tests/Python/PythonPackagesTests.cs +++ b/Tests/Python/PythonPackagesTests.cs @@ -2977,7 +2977,8 @@ public void DotNetLoadsPythonEnvironmentOpenSsl() using (Py.GIL()) { using var sys = Py.Import("sys"); - pythonPrefix = sys.GetAttr("prefix").As(); + // a virtual environment keeps using its base installation's native libraries + pythonPrefix = sys.GetAttr("base_prefix").As(); } var openSslLibraries = File.ReadLines("/proc/self/maps") .Select(line => line.Split(' ', StringSplitOptions.RemoveEmptyEntries).Last())