Source: openjpeg2
Severity: important
Tags: security upstream patch
X-Debbugs-Cc: [email protected]

Hi,

opj_j2k_read_sod() in src/lib/openjp2/j2k.c writes the end-of-header and
end-of-tile-part stream offsets into

cstr_index->tile_index[tileno].tp_index[current_tpsno]

without first checking that the tp_index array was allocated, or that
current_tpsno is within its allocated size (nb_tps). A crafted JPEG 2000
codestream that drives current_tpsno past the allocated tile-part index, or
that leaves tp_index NULL, causes a heap-buffer-overflow write during
decoding. The path is reached from opj_decode() through
opj_j2k_read_tile_header(), so decoding an untrusted .j2k/.jp2 file is
enough to trigger it; no special API use is required.

This was found by OSS-Fuzz (OSV-2025-219, heap-buffer-overflow WRITE in
opj_j2k_read_tile_header). I could not find a CVE assigned for it, nor an
existing bug in the BTS.

Upstream fixed it in pull request 1621, merged as commit d33cbec on main,
but no release has been cut that includes the fix, so all current Debian
versions are still affected:

sid/forky 2.5.4-1.1
trixie 2.5.3-2.1~deb13u2
bookworm 2.5.0-2+deb12u3

The vulnerable code is identical in all three, so the attached DEP-3 patch
applies cleanly to each. It is a straight backport of the upstream guard:
write the offsets only when tp_index is non-NULL and current_tpsno < nb_tps.
I confirmed it applies to the 2.5.4, 2.5.3 and 2.5.0 sources; the change is
a
bounds check only and does not affect decoding of valid files. I did not
rebuild each package separately.

Regards,
Sumit
Description: Guard tp_index write in opj_j2k_read_sod against heap overflow
 opj_j2k_read_sod() records the end-of-header and end-of-tile-part stream
 offsets into cstr_index->tile_index[tileno].tp_index[current_tpsno] without
 checking that the tp_index array has been allocated or that current_tpsno is
 within its bounds (nb_tps). A crafted JPEG 2000 codestream that drives
 current_tpsno past the allocated tile-part index (or leaves tp_index NULL)
 therefore causes a heap-buffer-overflow write during decoding, reachable from
 opj_decode() via opj_j2k_read_tile_header(). Reported by OSS-Fuzz as
 OSV-2025-219.
 .
 Only write the offsets when tp_index is non-NULL and current_tpsno < nb_tps.
 This is a backport of the upstream fix (PR 1621, merged as d33cbec on main and
 not yet in any release); the guard logic is identical to upstream, only the
 brace indentation differs to match the released source formatting.
Origin: backport, https://github.com/uclouvain/openjpeg/commit/d33cbecc148d3affcdf403211fddc2cc5d442379
Bug: https://github.com/uclouvain/openjpeg/issues/1620
Bug-OSV: https://osv.dev/vulnerability/OSV-2025-219
Forwarded: not-needed
Last-Update: 2026-11-06
--- a/src/lib/openjp2/j2k.c
+++ b/src/lib/openjp2/j2k.c
@@ -5082,12 +5082,16 @@
 
         OPJ_UINT32 l_current_tile_part =
             l_cstr_index->tile_index[p_j2k->m_current_tile_number].current_tpsno;
-        l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_header
-            =
-                l_current_pos;
-        l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_pos
-            =
-                l_current_pos + p_j2k->m_specific_param.m_decoder.m_sot_length + 2;
+        if (l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index &&
+                l_current_tile_part <
+                l_cstr_index->tile_index[p_j2k->m_current_tile_number].nb_tps) {
+            l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_header
+                =
+                    l_current_pos;
+            l_cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index[l_current_tile_part].end_pos
+                =
+                    l_current_pos + p_j2k->m_specific_param.m_decoder.m_sot_length + 2;
+        }
 
         if (OPJ_FALSE == opj_j2k_add_tlmarker(p_j2k->m_current_tile_number,
                                               l_cstr_index,

Reply via email to