The OpenSSL we ship is out of support, and its assembly cannot carry branch protection - #231
Merged
Merged
Conversation
OpenSSL 3.0 has left support, so the statics we ship receive no more fixes. 3.5 is the current LTS and is maintained to 2030. The bump is also the only way to finish what #229 started. That change gave arm64 pointer authentication and branch target identification, but libhttrack.so came out with landing pads and no .note.gnu.property. The linker ANDs that note over every input, and the OpenSSL statics carried none. 3.0.15 cannot carry one, because its crypto/arm_arch.h has no BTI or PAC support, so no flag makes its assembly emit pads. Those macros arrived in 3.2.0. I built both to check. At 3.0.15 with the flag, 859 of 872 libcrypto.a members take the note, and the 13 without it are exactly the arm64 assembly. That is enough to clear the note for the whole library. At 3.5.8 all 982 take it, the engine still compiles and links, and libhttrack.so now reports BTI and PAC with retaa still at 0. x86_64 gets no control-flow flag, because lld drops the CET note on that target, which #230 measured. The image recipe now also builds on a pull request, without publishing. A broken OpenSSL build used to reach master before anything ran it. Signed-off-by: Xavier Roche <xroche@gmail.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3.5 raises OPENSSL_TLS_SECURITY_LEVEL from 1 to 2, and ssl_cert.c reads that macro to set each context's default. The engine never calls SSL_CTX_set_security_level, so it inherits whatever the library shipped with. Level 2 lifts the floor from 80 bits to 112. That refuses a 1024-bit DH group and a SHA-1 signature algorithm, which servers untouched since Logjam still offer. HTTrack exists to copy old sites, so the bump would have broken crawls that work today. The certificate-side tightenings do not bite, because the engine verifies no certificate by design, but these two checks run whatever verify_mode says. The macro sits behind an #ifndef, so -DOPENSSL_TLS_SECURITY_LEVEL=1 pins what 3.0.15 shipped. I read it back out of the built libssl.a. ssl_cert_new stores 1 with the define and 2 without it, at the same instruction. Branch protection is unaffected, and all 982 libcrypto.a members still carry the note. Pinning also stops the next bump moving it again. The engine should set the level itself rather than inherit it, but that change belongs to the httrack repo. Signed-off-by: Xavier Roche <xroche@gmail.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
xroche
enabled auto-merge (squash)
September 21, 2026 19:39
android.yml and codeql.yml each set OPENSSL_VERSION and passed it to the script without the matching OPENSSL_SHA256. After the bump they would have fetched 3.0.15 and checked it against 3.5.8's digest, so both jobs would fail. They now pass no version at all and the script's default rules. The cache key moves with them. It keyed on the version, so a new compile flag at an unchanged version would have restored a stale OpenSSL and hidden the flag. It now keys on a hash of the recipe, which the branch protection flag needs. A version override that carries no hash is refused outright, because the default hash belongs to the default version. Signed-off-by: Xavier Roche <xroche@gmail.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
xroche
added a commit
that referenced
this pull request
Sep 21, 2026
Two ways an arm64 library can lose its branch protection, both silent. A library built without `-mbranch-protection` still loads and passes every test. An `-march` bump to armv8.3-a turns the PAC hints into `retaa`, which faults on an ARMv8.0 core. On every arm64 `.so` the check wants no `retaa` or `retab`, one `paciasp` in the instruction column, and one feature note naming BTI and PAC. It refuses an empty walk, a directory it could not read, and a failing tool, because each of those otherwise reads as a pass. I ran it against real libraries on both sides. The ones built before #231 fail on `libhttrack.so`, whose note the unmarked OpenSSL statics cleared, and the ones built after it pass. A real build only produces the passing case, so the test drives the failures through stubs that copy the real tools' output, lowercase `aarch64 feature` included. Six mutations of the checker each turn exactly one case red. The note assertion is right only now. Before #231 it was absent from a correctly built `libhttrack.so`. --------- Signed-off-by: Xavier Roche <xroche@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
OpenSSL 3.0 has left support, so the statics we ship receive no more fixes. 3.5 is the current LTS.
The bump is also the only way to finish #229. That change gave arm64 pointer authentication and branch target identification, but
libhttrack.sogot landing pads and no.note.gnu.property. The linker ANDs that note over every input, and 3.0.15's assembly cannot carry one, becausecrypto/arm_arch.hgained BTI support only in 3.2.0. At 3.5.8 all 982libcrypto.amembers are marked, andlibhttrack.sonow reportsBTI, PAC.3.5 also raises the default TLS security level from 1 to 2, which the engine inherits because it never calls
SSL_CTX_set_security_level. Level 2 refuses 1024-bit DH groups and SHA-1 signature algorithms, so crawls of old sites that work today would fail.-DOPENSSL_TLS_SECURITY_LEVEL=1pins what 3.0.15 shipped, read back from the builtlibssl.a.The version lived in four places. Two passed it to the script without the matching hash, so they would have checked 3.0.15 against 3.5.8's digest and failed. The script now owns the version alone. The OpenSSL cache keyed on the version too, so a new compile flag at an unchanged version would have restored a stale build. It keys on the recipe now.
Two gaps remain. The engine should set the security level itself, which belongs to the httrack repo. And 3.5 leads its group list with
X25519MLKEM768, so the ClientHello grows past 1.4 KB and some old stacks mishandle that.