Skip to content

Document the object serialization format change in IoBuffer.putObject/getObject - #63

Open
L1nq0 wants to merge 1 commit into
apache:2.2.Xfrom
L1nq0:serialization-format-note
Open

L1nq0 wants to merge 1 commit into
apache:2.2.Xfrom
L1nq0:serialization-format-note

Conversation

@L1nq0

@L1nq0 L1nq0 commented Sep 14, 2026

Copy link
Copy Markdown

The CVE-2026-47065 fix in 2.2.8 (commit 409171d) changed the form of a serialized object on the wire: writeClassDescriptor now appends the full standard Java serialization descriptor after the tag and class name, where 2.2.7 wrote only the tag and the name. Arrays, primitives and non-Serializable classes are unchanged.

Object streams exchanged through IoBuffer.putObject / getObject are therefore not interoperable across the 2.2.7 / 2.2.8 boundary, in either direction. The same HashMap written by both versions:

2.2.7, 59 bytes
00000037aced000573720100116a6176612e7574696c2e486173684d617078703f4000000000000c770800000010000000017400016b7400017678

2.2.8, 114 bytes
0000006eaced000573720100116a6176612e7574696c2e486173684d617000116a6176612e7574696c2e486173684d61700507dac1c31660d103000246000a6c6f6164466163746f724900097468726573686f6c6478703f4000000000000c770800000010000000017400016b7400017678

A 2.2.7 stream read by 2.2.8 or 2.2.9 fails with a BufferDataException wrapping an EOFException. A 2.2.8 stream read by 2.2.7 fails with a BufferDataException wrapping a StreamCorruptedException (invalid type code: 00). Same-version reads succeed on both sides. Reproduced with mina-core 2.2.7 / 2.2.8 / 2.2.9 from Maven Central on JDK 8, using a plain HashMap written with IoBuffer.putObject and read back with getObject after accept("java.util.*").

Mixed-version deployments hit this during rolling upgrades, and payloads queued or persisted before an upgrade become unreadable after it. The format change is not mentioned in the release announcement or the advisory, so users applying the security upgrade get no signal that persisted or in-flight payloads will break.

This change documents the format where users will look for it: the full statement on IoBuffer.putObject, a pointer on both getObject overloads. The same format change is present on the 2.1.x and 2.0.x branches (first released in 2.1.13 and 2.0.29); I verified the behavior on the 2.2.x line only. I can provide backports of this note to the other branches, and the small test program, if that helps.

@elecharny

Copy link
Copy Markdown
Contributor

Indeed, this is unfortunate :/ It's also true for MINA 2.1.15 and MINA 2.0.30.
I can apply your suggested patch, but I guess we also need to add a warning on the web site...

@L1nq0

L1nq0 commented Sep 15, 2026

Copy link
Copy Markdown
Author

Thanks for taking a look, and yes, a note on the site would reach people who never open the javadoc.

Since the warning and any backports will need exact version numbers, I ran the same check on the 2.1.x and 2.0.x release lines (Maven Central jars, JDK 21; outputs byte-identical to the JDK 8 runs in the description). The first releases carrying the new form are 2.1.13 and 2.0.29, so the version pairs for the notes are 2.2.7/2.2.8, 2.1.12/2.1.13 and 2.0.28/2.0.29.

2.0.28, 2.1.12 and 2.2.7 all write the same 59-byte stream, and 2.0.29, 2.0.30, 2.1.13, 2.1.15 and 2.2.8 all write the same 114-byte stream. Reads across each boundary fail in both directions with the same two failures as on 2.2.x: BufferDataException wrapping an EOFException one way, a StreamCorruptedException the other. 2.1.15 and 2.0.30 read streams from 2.1.13 and 2.0.29 fine and reject the older ones.

I can open the same javadoc change against the 2.1.X and 2.0.X branches with the version numbers adapted, or paste both diffs here for you to apply, whichever is less work for you.

For the site warning, draft wording in case it saves a minute:

The fix for CVE-2026-47065 changed the form MINA writes for serialized objects exchanged through IoBuffer.putObject / getObject and ObjectSerializationCodecFactory: after the class name, the full standard Java serialization class descriptor is now written. Streams produced by 2.2.7, 2.1.12 or 2.0.28 and earlier cannot be read by 2.2.8, 2.1.13 or 2.0.29 and later, and streams produced by the newer releases cannot be read by the older ones. Arrays, primitives and non-Serializable classes are unaffected. Upgrades across this boundary fail with a BufferDataException wrapping an EOFException or a StreamCorruptedException, and payloads persisted before the upgrade become unreadable after it.

@elecharny

Copy link
Copy Markdown
Contributor

Hi @L1nq0, thanks for the quick proposal, I have updated the web site to reflect the change (https://mina.apache.org/mina-project/). It should be visible in a matter of minutes (the time for the framework to compile the page and expose it).

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.

2 participants