Skip to content

Commit

Permalink
Fix an integer underflow bug in patch decoding.
Browse files Browse the repository at this point in the history
When reading patches, the code doesn't properly check that all patches
are in bounds.

In particular, if the start of a patch becomes negative (due to the
delta coding of patch positions), but not negative *enough* to cause
`start + size` to still be negative, the decoder happily accepted the
patch. Such a patch would then lead the interval tree building code to
run into an infinite loop.
  • Loading branch information
veluca93 committed Jun 9, 2023
1 parent cf760b8 commit d4e67a6
Showing 1 changed file with 14 additions and 4 deletions.
18 changes: 14 additions & 4 deletions lib/jxl/dec_patch_dictionary.cc
Expand Up @@ -107,10 +107,20 @@ Status PatchDictionary::Decode(BitReader* br, size_t xsize, size_t ysize,
pos.x = read_num(kPatchPositionContext);
pos.y = read_num(kPatchPositionContext);
} else {
pos.x =
positions_.back().x + UnpackSigned(read_num(kPatchOffsetContext));
pos.y =
positions_.back().y + UnpackSigned(read_num(kPatchOffsetContext));
ssize_t deltax = UnpackSigned(read_num(kPatchOffsetContext));
if (deltax < 0 && static_cast<size_t>(-deltax) > positions_.back().x) {
return JXL_FAILURE("Invalid patch: negative x coordinate (%" PRIuS
" base x %" PRIdS " delta x)",
positions_.back().x, deltax);
}
pos.x = positions_.back().x + deltax;
ssize_t deltay = UnpackSigned(read_num(kPatchOffsetContext));
if (deltay < 0 && static_cast<size_t>(-deltay) > positions_.back().y) {
return JXL_FAILURE("Invalid patch: negative y coordinate (%" PRIuS
" base y %" PRIdS " delta y)",
positions_.back().y, deltay);
}
pos.y = positions_.back().y + deltay;
}
if (pos.x + ref_pos.xsize > xsize) {
return JXL_FAILURE("Invalid patch x: at %" PRIuS " + %" PRIuS
Expand Down

0 comments on commit d4e67a6

Please sign in to comment.