Skip to content

bc-fips 2.1.3: per-key Cleaner registration (CVE-2026-13505 fix) causes long G1 young-GC pauses on JDK 21 #2522

Open

Description

@sivarank

After upgrading bc-fips 2.1.2 → 2.1.3 we see a significant regression in G1 young-GC pause times on JDK 21 for workloads that perform many Cipher.init() calls (AES/CBC/PKCS7Padding via the BCFIPS provider). Pauses also grow with JVM uptime. Rolling the jar back to 2.1.2 is our current mitigation.

We believe the cause is the new java.lang.ref.Cleaner registration introduced by the CVE-2026-13505 fix, each Cleaner keeps its registrations in a single doubly-linked list that G1 has to walk serially .

Environment
bc-fips 2.1.3 (also bctls-fips 2.1.24, bcutil-fips 2.1.7), multi-release jar loaded on Java 9+
Eclipse Temurin 21.0.12.1+1, G1 GC, 28–60 GB heap, 17–32 parallel GC workers, Linux containers (cgroup v2)
Workload: high-rate symmetric decryption (AES/CBC/PKCS7Padding). The app calls Cipher.getInstance + Cipher.init per operation, which is not ideal but is very common.

In 2.1.2 the Java 9+ SymmetricSecretKey had no finalizer and no Cleaner, so this is a net-new phantom reference per key. A key is created on every Cipher.init (via jcajce.provider.Utils.convertKey).

The same pattern (one private static Cleaner.create() per class) was added to the following classes, giving 7 Cleaners / 7 Cleaner-N daemon threads in total: - AESWorkingBuffer, which replaces the finalizer in AESEngine$WorkingBuffer - CTRDRBGWorkingBuffer, HMacDRBGWorkingBuffer, HashDRBGWorkingBuffer - DESedeWorkingBuffer - SecretZeroizer

Questions / requests
Is this regression known, and is a fix planned for a 2.1.x release?
Could the per-key Cleaner registration be made opt-out via a system/security property (for example for environments that already call destroy() or accept the CVE-2026-13505 risk)?
Could BC use one shared Cleaner (or a small sharded set) instead of 7 per-class static Cleaners?
Will this setting org.bouncycastle.native.cleanup_priority =? medium/high help here?

References
CVE-2026-13505 wiki: https://github.com/bcgit/bc-java/wiki/CVE%E2%80%902026%E2%80%9013505
JDK-8343704 "Bad GC parallelism with processing Cleaner queues": https://bugs.openjdk.org/browse/JDK-8343704
Related history: #1776 (finalizers), #2121 (DisposalDaemon memory)

Activity

  1. dghgit commented on Oct 22, 2026

    @dghgit
    Contributor

    I know this is going to sound a bit weird, but the cleaner code was introduced to remove GC issues with the approach taken in 2.1.2 for Java 11 and later. That it fixed these issues was also confirmed, so this is not a regression. Reading the JDK issue, it appears the actual problem is fixed in Java 24. Does this show up in Java 25 as well? If it it doesn't, I'd suggest getting in touch with Oracle about getting the issue back-ported to Java 21. If it does, it's not likely that it's related to the Cleaner classes, but it may still be something we can fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions