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,
