Add system-OpenSSL build variant for the bundled Python 3.10.13 Linux package - #376
Add system-OpenSSL build variant for the bundled Python 3.10.13 Linux package#376nickschuetz wants to merge 1 commit into
Conversation
Adds a parallel Linux build variant that links Python's _ssl dynamically against the building distro's system OpenSSL 3.x instead of the bundled OpenSSL-1.1.1t package. Existing linux_x64/ variant stays unchanged. Motivation: OpenSSL 1.1.1t has been end-of-life since 2023-09-11. For downstream distribution packagers (Fedora, Debian, Arch, Alpine) targeting their distribution's review process, the EOL crypto in the bundled Python is a meaningful inclusion blocker. This variant gives those packagers a clean path: configure Python to find OpenSSL 3.x in the system at build time, link dynamically, let the OS handle CVE updates. Changes: - docker_build_linux.sh: env-var (PYTHON_USE_SYSTEM_OPENSSL=1) switches --with-openssl=<bundle> to --with-openssl=/usr --with-openssl-rpath=auto, conditional LICENSE.OPENSSL copy (only for bundled variant). - Dockerfile: add libssl-dev (required for system variant, harmless for bundled). - build-linux.sh: detect variant from docker image name (contains "system_openssl"), pass env through to docker run. - build_config.json: add Linux-system-openssl sub-variant. Default Linux + Linux-aarch64 variants unchanged. Output package: python-3.10.13-rev1-linux-system-openssl Long-term: dynamic variant reduces O3DE maintainers' CVE-response burden (OS handles OpenSSL updates) while the bundled variant remains the floor for portability-sensitive consumers. Filed in coordination with the downstream Fedora packaging effort at github.com/nickschuetz/o3de-rpm; see that repo's upstream-drafts/pr-python-system-openssl.md for the full motivation and validation plan. Signed-off-by: Nick Schuetz <nschuetz@redhat.com>
PR filed at o3de/3p-package-source#376 on 2026-05-28 per Nick's explicit "submit the PR upstream" approval. DCO signoff present; em-dash audit clean; prior-art sweep clean. Draft status line updated to SUBMITTED with the PR URL. Full motivation + diff + validation evidence preserved in the draft body for ongoing reference. Signed-off-by: Nick Schuetz <nschuetz@redhat.com>
|
We might need to go deep in the history, but the question first. Any idea why OpenSSL was bundled into O3DE? I started working on bundling new OpenSSL for a simple reason. OpenSSL 1.1.1 is burned into |
|
Up: #387 |
|
Thanks for grabbing this, Jan, and #387 is the right call. Bumping the bundle to 3.6.3 kills the EOL 1.1.1 problem for everyone, which is the bigger win of the two. Why it was bundled in the first place: no idea for certain, I never found a decision record. My guess is it just rode the general "bundle everything so builds are hermetic and work offline everywhere" convention rather than anyone choosing OpenSSL specifically. Whatever the original reason, your AzNetworking catch is what pins it in place now it seems. It highlights that ripping the bundle out might not be as simple as it looks. On bundle vs. system: I'd keep bundled-by-default and just offer a system-link variant next to it, which is all #376 is. So the two PRs don't conflict: #387 makes the default bundle fine again by getting it off dead crypto, and #376 lets distro builds (Fedora and friends) link the OS OpenSSL so CVEs come through dnf/apt instead of a rebuild. Even a 3.6.3 bundle is still a bundled lib, which Fedora frowns on regardless of version, so #376 stays useful to us after yours lands. Happy to rebase #376 on top of #387 and re-validate against the 3.6.3 bundle once it settles, or fold it into your sweep if that's less review churn. Thanks for driving this. |
|
Since the question of what actually happens when 1.1.1 and 3.x end up in the same process came up, I went and measured it on our Fedora packages rather than guessing. Posting in case it's useful. What's in there today: The good news is it doesn't actually cross-bind. I traced it with So the "as long as they all match" instinct is right, and it turns out symbol versioning is what quietly enforces it. Worth knowing that the mixed state isn't automatically fatal, but also that nothing is checking it for you. On the "we may have to ship a new python" point from the #387 review, that's confirmed from this side: the stock Offer from my earlier comment still stands, happy to rebase this onto #387 and re-validate once that merges. |
|
I have a Gem that depends on OpenSSL 3.x and I was getting a segfault every time I added the Gem to the project due to the collisions between the embedded (in |
|
I dug into this properly and reproduced it, and I have to correct something I said earlier in the thread: I claimed the two OpenSSLs don't cross-bind and that symbol versioning keeps them apart. That's wrong. It does cross-bind, and versioning does not save you. Here's what actually happens. Repro: a small "gem" .so linked against system OpenSSL 3.x doing an EC keygen. Standalone it works. Load AzFramework into the process first (it exports its statically-linked 1.1.1t symbols into global scope, unhidden) and the same keygen fails with The mechanism is nastier than I first thought. It's not that libcrypto's internals get hijacked, they don't. It's that the gem's own calls get split across the two versions. glibc will happily bind a versioned reference ( So versioning is not the safety net I said it was, an unversioned export shadows a versioned one. Which also means #387 alone won't fully fix it: getting everyone on 3.x removes the version mismatch, but AzFramework still exports a whole second copy of OpenSSL globally, so a gem's libcrypto and AzFramework's still fight over the common symbols. The fix is to stop exporting them, hidden visibility on AzNetworking's OpenSSL. I confirmed the direction: loading AzFramework with local scope ( If you can share a minimal repro of your gem crash I'll run it against our Fedora build and get you the precise per-symbol trace for your case. |
I have some work in progress for O3DE, I will publish it when I get some time to work on it. There are two things that should be solved. There are different applications. For me, #387 is a good step forward. I can easily link my gem against AzNetworking and get the access to OpenSSL 3.x, which is required by the rest of my infrastructure (1.1.1 is deprecated). |
Summary
Adds a parallel Linux build variant for the bundled Python 3.10.13 package that links dynamically against the building distro's system OpenSSL 3.x rather than the bundled
OpenSSL-1.1.1t-rev1-linuxstatic dependency.Motivation
The bundled
OpenSSL-1.1.1tis end-of-life since 2023-09-11. For downstream distribution packagers (Fedora, Debian, Arch, Alpine) targeting their distribution's review process, the EOL crypto in the bundled Python is a meaningful inclusion blocker. This variant gives those packagers a clean path: configure Python to find OpenSSL 3.x in the system at build time, link dynamically, let the OS handle CVE updates.What this PR does
The existing
linux_x64/variant is unchanged. A newLinux-system-opensslsub-variant inbuild_config.jsontriggers an env-var (PYTHON_USE_SYSTEM_OPENSSL=1) that the modifieddocker_build_linux.shreads. In that mode:--with-openssl=/usr --with-openssl-rpath=autoreplaces--with-openssl=<bundled path>libssl-devavailable (added to the Dockerfile)_ssl.cpython-310-x86_64-linux-gnu.soends up dynamically linking against the OS'slibssl.so.3+libcrypto.so.3Output package:
python-3.10.13-rev1-linux-system-openssl. Drop-in replacement for downstream consumers whose target OS provides OpenSSL 3.x; Python ABI is 3.10.13 stable.Compatibility
The new variant requires the target system to have OpenSSL 3.x in the base OS at runtime (
libssl.so.3+libcrypto.so.3). Target distros with OpenSSL 3.x in base: Ubuntu 22.04 LTS and newer, Fedora 39 and newer, RHEL 9 and newer, Debian 12 and newer. Existing consumers on older OSes (Ubuntu 20.04 LTS, RHEL 8, Debian 11) ship OpenSSL 1.1.x and would not work with the system-openssl variant; they keep using the existinglinux_x64/variant unchanged. Offline-install scenarios on older targets are unaffected because the default bundled variant is fully self-contained.Validation
Spike validation completed locally before this PR. Net: 78 individual checks across the integration tier suite, 0 failures.
Build: PASS. Full
pull_and_build_from_git.py package-system/python --platform-name Linux-system-openssl --cleanran clean inside an Ubuntu 22.04 container. Configure detected system OpenSSL (checking for openssl/ssl.h in /usr... yes), and theBuilding Python against system OpenSSL (dynamic link)env-var-driven branch executed correctly. FinalPYTHON WAS BUILT FROM SOURCEmarker reached.Artifact:
ldd _ssl.cpython-310-x86_64-linux-gnu.soshowslibssl.so.3 => /lib/x86_64-linux-gnu/libssl.so.3+libcrypto.so.3 => /lib/x86_64-linux-gnu/libcrypto.so.3(Ubuntu container). On a Fedora 44 host, resolves to/lib64/libssl.so.3+/lib64/libcrypto.so.3(OpenSSL 3.x stable ABI holds across the build-host / runtime-host boundary).import ssl; print(ssl.OPENSSL_VERSION)returnsOpenSSL 3.0.2 15 Mar 2022(Ubuntu 22.04 container) andOpenSSL 3.5.5 27 Jan 2026(Fedora 44 host).Engine smoke (downstream Fedora packaging effort):
~/.o3de/Python/venvto force re-bootstrap viaget_python.sh, ran the integration tier suite.get_python.sh, manifest registration viao3de-cli register --this-engine): PASS. This is the critical OpenSSL-path canary: pip install runs HTTPS through the rebuilt_sslmodule; manifest setup and registry work correctly.o3de create-project+ cmake configure): PASSCharacterSample): 7/7 PASSThe engine works identically with the rebuilt Python. AssetProcessor's embedded Python interpreter executes builders cleanly. PySide2 (separate bundled package, links against
libpython3.10.so.1.0) loads without ABI issues; Python's stable patch-level ABI held.Open questions for sig-build
build_config.jsonso each variant picks its own (preserves existing artifact-byte-equivalence for the bundled-OpenSSL build), or (b) bump the default base to 22.04 for both variants (simpler maintenance). Happy to refactor either way.python-3.10.13-rev1-linux-system-opensslis verbose. Alternatives:python-3.10.13-rev1-linux-dynamic-ssl,python-3.10.13-system-ssl-rev1-linux, etc. Whatever convention sig-build prefers.apt-get update/dnf updateinstead of requiring a Python rebuild every time OpenSSL ships a CVE). The bundled variant remains useful for environments where system OpenSSL can't be assumed (older containers, embedded targets, build-isolated CI, air-gapped offline-install on older OSes). Suggest both variants coexist long-term.Notes
upstream-drafts/pr-python-system-openssl.mdfor the full motivation and validation evidence.