term: protect against integer overflow when accumulating scroll damage

When accumulating scroll damage, we check if the last scroll damage’s
scrolling region, and type, matches the new/current scroll damage. If
so, the number of lines in the last scroll damage is increased,
instead of adding a new scroll damage instance to the list.

If the scroll damage list isn’t consumed, this build up of scroll
damage would eventually overflow.

And, even if it didn’t overflow, it could become large enough, that
when later used to calculate e.g. the affected surface area, while
rendering a frame, would cause an overflow there instead.

This patch fixes both issues by:

a) do an overflow check before increasing the line count
b) limit the line count to UINT16_MAX
This commit is contained in:
Daniel Eklöf 2023-03-28 18:37:41 +02:00
parent 7bc22862fa
commit 981e4b77cb
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
3 changed files with 13 additions and 7 deletions

View file

@ -2252,15 +2252,20 @@ void
term_damage_scroll(struct terminal *term, enum damage_type damage_type,
struct scroll_region region, int lines)
{
if (tll_length(term->grid->scroll_damage) > 0) {
if (likely(tll_length(term->grid->scroll_damage) > 0)) {
struct damage *dmg = &tll_back(term->grid->scroll_damage);
if (dmg->type == damage_type &&
dmg->region.start == region.start &&
dmg->region.end == region.end)
if (likely(
dmg->type == damage_type &&
dmg->region.start == region.start &&
dmg->region.end == region.end))
{
dmg->lines += lines;
return;
/* Make sure we dont overflow... */
int new_line_count = (int)dmg->lines + lines;
if (likely(new_line_count <= UINT16_MAX)) {
dmg->lines = new_line_count;
return;
}
}
}
struct damage dmg = {