libpayload/cbgfx: Fix overflow in transform_vector()

Fix potential overflow when multiplying integers in transform_vector().
This issue is causing the absolute coordinate of the bottom right corner
of the box to be incorrectly calculated for draw_rounded_box(), which is
used in menu UI to clear the previous screen.

In addition, check the lower bound in within_box().

BRANCH=none
BUG=b:146399181, b:159772149
TEST=emerge-puff libpayload
TEST=Previous screen is cleared properly for menu UI

Change-Id: I57845f54e18e5bdbd0d774209ee9632cb860b0c2
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/42770
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Shelley Chen <shchen@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Yu-Ping Wu 2020-06-24 17:28:22 +08:00 committed by Patrick Georgi
parent be1ff7eb72
commit 373ae2e734
1 changed files with 11 additions and 7 deletions

View File

@ -113,22 +113,26 @@ static int transform_vector(struct vector *out,
{ {
if (!is_valid_scale(a)) if (!is_valid_scale(a))
return CBGFX_ERROR_INVALID_PARAMETER; return CBGFX_ERROR_INVALID_PARAMETER;
out->x = a->x.n * in->x / a->x.d + offset->x; out->x = (int64_t)a->x.n * in->x / a->x.d + offset->x;
out->y = a->y.n * in->y / a->y.d + offset->y; out->y = (int64_t)a->y.n * in->y / a->y.d + offset->y;
return CBGFX_SUCCESS; return CBGFX_SUCCESS;
} }
/* /*
* Returns 1 if v is exclusively within box, 0 if v is inclusively within box, * Returns 1 if v is exclusively within box, 0 if v is inclusively within box,
* or -1 otherwise. Note that only the right and bottom edges are examined. * or -1 otherwise.
*/ */
static int within_box(const struct vector *v, const struct rect *bound) static int within_box(const struct vector *v, const struct rect *bound)
{ {
if (v->x < bound->offset.x + bound->size.width && if (v->x > bound->offset.x &&
v->y < bound->offset.y + bound->size.height) v->y > bound->offset.y &&
v->x < bound->offset.x + bound->size.width &&
v->y < bound->offset.y + bound->size.height)
return 1; return 1;
else if (v->x <= bound->offset.x + bound->size.width && else if (v->x >= bound->offset.x &&
v->y <= bound->offset.y + bound->size.height) v->y >= bound->offset.y &&
v->x <= bound->offset.x + bound->size.width &&
v->y <= bound->offset.y + bound->size.height)
return 0; return 0;
else else
return -1; return -1;