Skip to content

Stop old openssl extensions clashing with OpenSSL 3, add missing 2.7/3.0/3.1/3.2.0 - #14

Merged
excid3 merged 2 commits into
mainfrom
hide-openssl-ext-symbols
Sep 30, 2026
Merged

excid3 merged 2 commits into
mainfrom
hide-openssl-ext-symbols

Conversation

@excid3

@excid3 excid3 commented Sep 29, 2026

Copy link
Copy Markdown
Member

Problem

After #12, Ruby 1.8.7, 1.9.3, 2.0.0 and 2.1.10 still segfault when pg is required before openssl (Bundler's usual order):

libcrypto.so.3(CRYPTO_set_ex_data) <- openssl.so  [BUG] Segmentation fault  (openssl/ssl.rb:71)

Their ext/openssl defines and exports its own X509_STORE_get_ex_data/X509_STORE_set_ex_data (and SSL_SESSION_cmp), and 1.8's digest/sha2 exports SHA256_Transform. With libpq's libcrypto.so.3 already loaded, calls to them bind to OpenSSL 3's real functions. --exclude-libs hides the bundled static OpenSSL, but not symbols the extension itself defines.

Fix

  • New init_only_exports source patch (series 1.8–3.1): openssl and digest/{md5,sha1,sha2,rmd160} link with a version script exporting only Init_*. The flag goes into those extensions' Makefiles only, not rbconfig, so native gems are unaffected.
  • check_openssl_hidden! now fails if those extensions export anything but Init_* (for patched series).
  • Adds recipes for 2.7.0–2.7.7, 3.0.0–3.0.6, 3.1.0–3.1.6 and 3.2.0, which Hatchbox's S3 bucket has, so the fork can replace it.

Testing

Built locally with bin/package-linux (arm64): 1.8.7-p374, 2.1.10, 2.3.8, 3.1.7, 2.7.0, 3.0.0, 3.2.0 (both variants). All pass the package's own checks. Then on Ubuntu 24.04, each installed into ~/.asdf/installs/ruby/<v>, pg built from source against system libpq 16, in both require orders: pg to a TLS Postgres 17 (TLSv1.3) and Net::HTTPS to rubygems.org with peer verification. All pass (1.8.7 needs an explicit ca_file, as 1.8's net/http always has).

After merge

New versions release via release-new. Existing old-series versions need a dispatch of Release New Versions with only:
1.8.7-p374 1.9.3-p551 2.0.0-p648 2.1.10 2.2.10 2.3.8 2.4.10 2.5.9 2.6.10 2.7.8 3.0.7 3.1.7

Ruby 1.8-2.3's openssl extension defines and exports stand-ins for functions
its OpenSSL lacks (X509_STORE_set_ex_data, SSL_SESSION_cmp), and 1.8's
digest/sha2 exports SHA256_Transform. With the pg gem required before openssl,
the system libcrypto.so.3 is already loaded and those calls bind to OpenSSL 3's
functions, which segfault on 1.x structs (seen on 1.8.7, 1.9.3, 2.0.0, 2.1.10).

Link these extensions with a version script that exports only Init_*, and have
check_openssl_hidden! fail if they export anything else.
Hatchbox's S3 bucket carries these, so the fork needs them before it replaces
S3. 3.2.0 was dropped upstream for a header path bug; it now builds and
compiles native gems (pg from source) in both variants.
@excid3
excid3 merged commit 4667f92 into main Sep 30, 2026
7 checks passed
@excid3
excid3 deleted the hide-openssl-ext-symbols branch September 30, 2026 13:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant