VYPR
Critical severityNVD Advisory· Published Nov 7, 2022· Updated Aug 3, 2024

Apache Commons BCEL prior to 6.6.0 allows producing arbitrary bytecode via out-of-bounds writing

CVE-2022-42920

Description

Apache Commons BCEL APIs permit out-of-bounds writes, enabling attacker-controlled data to produce arbitrary bytecode; fixed in 6.6.0.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Apache Commons BCEL APIs permit out-of-bounds writes, enabling attacker-controlled data to produce arbitrary bytecode; fixed in 6.6.0.

Vulnerability

Description

Apache Commons BCEL (Byte Code Engineering Library) before version 6.6.0 contains an out-of-bounds write vulnerability in its APIs that normally only permit altering specific class characteristics. Specifically, the ConstantPoolGen class does not enforce a limit on the number of constants written to the constant pool, allowing the generation of class files that exceed valid bounds [1][2]. This flaw can be exploited by attackers who provide crafted data to these APIs, resulting in the production of arbitrary bytecode beyond what the API normally allows [1][2].

Exploitation

The attack surface involves any application that passes attacker-controllable data to the affected BCEL APIs, which may be common in scenarios where user input influences class generation or modification [1]. The out-of-bounds condition is triggered when the constant pool size grows beyond the expected limits, effectively allowing an attacker to inject arbitrary bytecode into the class file [2][3]. No special privileges beyond the ability to supply input to such APIs are required.

Impact

Successful exploitation gives the attacker more control over the resulting bytecode than intended, potentially enabling arbitrary code execution or bypass of security constraints, depending on how the generated class is subsequently used [1][3]. Because the vulnerability originates in a widely used bytecode manipulation library (BCEL), many Java applications could be indirectly exposed.

Mitigation

The vulnerability is fixed in Apache Commons BCEL version 6.6.0, which enforces proper bounds on the constant pool size [2][3]. Users are urged to upgrade to this version or later (current release is 6.12.0 [4]). No workarounds are documented; the fix addresses the root cause by preventing out-of-bounds writes entirely.

AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.bcel:bcelMaven
< 6.6.06.6.0

Affected products

10

Patches

2
cf520ef45064

Fix release year.

https://github.com/apache/commons-bcelGary GregoryOct 12, 2022via osv
1 file changed · +1 1
  • src/changes/changes.xml+1 1 modified
    @@ -62,7 +62,7 @@ The <action> type attribute can be add,update,fix,remove.
        -->
    
     
    
       <body>
    
    -    <release version="6.6.0" date="2020-10-08" description="Minor feature and bug fix release.">
    
    +    <release version="6.6.0" date="2022-10-08" description="Minor feature and bug fix release.">
    
            <!-- FIX -->
    
           <action                  type="fix" dev="ggregory" due-to="Mark Roberts, Gary Gregory">Improve test case coverage; fix Utility.encode bug #46.</action>
    
           <action issue="BCEL-342" type="fix" dev="ggregory" due-to="Allon Murienik, Gary Gregory">Migrate test suite to JUnit Jupiter #68.</action>
    
    
f3267cbcc900

BCEL-363 Enforce MAX_CP_ENTRIES in ConstantPoolGen and ConstantPool.dump (#147)

https://github.com/apache/commons-bcelRichard AtkinsSep 21, 2022via ghsa-ref
3 files changed · +34 3
  • src/main/java/org/apache/bcel/classfile/ConstantPool.java+9 2 modified
    @@ -230,8 +230,15 @@ public ConstantPool copy() {
          * @throws IOException if problem in writeShort or dump
          */
         public void dump(final DataOutputStream file) throws IOException {
    -        file.writeShort(constantPool.length);
    -        for (int i = 1; i < constantPool.length; i++) {
    +        /*
    +         * Constants over the size of the constant pool shall not be written out.
    +         * This is a redundant measure as the ConstantPoolGen should have already
    +         * reported an error back in the situation.
    +        */
    +        final int size = Math.min(constantPool.length, Const.MAX_CP_ENTRIES);
    +
    +        file.writeShort(size);
    +        for (int i = 1; i < size; i++) {
                 if (constantPool[i] != null) {
                     constantPool[i].dump(file);
                 }
    
  • src/main/java/org/apache/bcel/generic/ConstantPoolGen.java+10 1 modified
    @@ -109,7 +109,7 @@ public ConstantPoolGen() {
         public ConstantPoolGen(final Constant[] cs) {
             final StringBuilder sb = new StringBuilder(DEFAULT_BUFFER_SIZE);
     
    -        size = Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64);
    +        size = Math.min(Math.max(DEFAULT_BUFFER_SIZE, cs.length + 64), Const.MAX_CP_ENTRIES + 1);
             constants = new Constant[size];
     
             System.arraycopy(cs, 0, constants, 0, cs.length);
    @@ -561,9 +561,18 @@ public int addUtf8(final String n) {
          * Resize internal array of constants.
          */
         protected void adjustSize() {
    +        // 3 extra spaces are needed as some entries may take 3 slots
    +        if (index + 3 >= Const.MAX_CP_ENTRIES + 1) {
    +            throw new IllegalStateException("The number of constants " + (index + 3)
    +                    + " is over the size of the constant pool: "
    +                    + Const.MAX_CP_ENTRIES);
    +        }
    +
             if (index + 3 >= size) {
                 final Constant[] cs = constants;
                 size *= 2;
    +            // the constant array shall not exceed the size of the constant pool
    +            size = Math.min(size, Const.MAX_CP_ENTRIES + 1);
                 constants = new Constant[size];
                 System.arraycopy(cs, 0, constants, 0, index);
             }
    
  • src/test/java/org/apache/bcel/classfile/ConstantPoolTestCase.java+15 0 modified
    @@ -18,8 +18,10 @@
     package org.apache.bcel.classfile;
     
     import static org.junit.jupiter.api.Assertions.assertNotNull;
    +import static org.junit.jupiter.api.Assertions.assertThrows;
     
     import org.apache.bcel.AbstractTestCase;
    +import org.apache.bcel.Const;
     import org.apache.bcel.generic.ConstantPoolGen;
     import org.apache.bcel.generic.InstructionHandle;
     import org.apache.bcel.generic.InstructionList;
    @@ -52,4 +54,17 @@ public void testConstantToString() throws ClassNotFoundException {
                 }
             }
         }
    +
    +    @Test
    +    public void testTooManyConstants() throws ClassNotFoundException {
    +        final JavaClass clazz = getTestClass(PACKAGE_BASE_NAME + ".data.SimpleClassWithDefaultConstructor");
    +        final ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
    +
    +        int i = cp.getSize();
    +        while (i < Const.MAX_CP_ENTRIES - 1) {
    +            cp.addLong(i);
    +            i = cp.getSize(); // i += 2
    +        }
    +        assertThrows(IllegalStateException.class, () -> cp.addLong(0));
    +    }
     }
    

Vulnerability mechanics

Root cause

"Missing bounds check on constant pool size allows out-of-bounds writes when adding constants beyond the JVM specification limit of 65535 entries."

Attack vector

An attacker who can supply attacker-controllable data to the ConstantPoolGen APIs (e.g., via a crafted Java class or serialized object) can trigger the out-of-bounds write by causing the internal constant array to grow beyond Const.MAX_CP_ENTRIES (65535). The ConstantPool.dump() method would then write more entries than the constant pool count field can represent, producing arbitrary bytecode. The attack requires no special authentication, only the ability to pass untrusted input to the affected BCEL APIs [patch_id=1641235].

Affected code

The vulnerability exists in ConstantPoolGen.java (adjustSize() and constructor) and ConstantPool.java (dump() method). The adjustSize() method in ConstantPoolGen could resize the internal constant array beyond Const.MAX_CP_ENTRIES without throwing an error, and dump() would write all entries regardless of the specification limit [patch_id=1641235].

What the fix does

The patch enforces a hard upper bound of Const.MAX_CP_ENTRIES (65535) in two places. In ConstantPoolGen, the constructor and adjustSize() method now cap the internal array size to MAX_CP_ENTRIES+1 and throw an IllegalStateException when the index would exceed the limit [patch_id=1641235]. In ConstantPool.dump(), the output loop is clamped to Math.min(constantPool.length, Const.MAX_CP_ENTRIES) as a redundant safety measure. Together these changes prevent the out-of-bounds write that could produce arbitrary bytecode.

Preconditions

  • inputAttacker must be able to pass attacker-controllable data to ConstantPoolGen APIs (e.g., via a crafted Java class or serialized object).
  • authNo authentication required beyond access to the application that uses Apache Commons BCEL to process untrusted input.

Generated on May 23, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

16

News mentions

0

No linked articles in our index yet.