https://github.com/cacalabs/libcaca/commit/46b4ea7cea72d6b3ffe65d33e604b1774dcc2bbd.patch From 46b4ea7cea72d6b3ffe65d33e604b1774dcc2bbd Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Fri, 26 Feb 2021 10:55:38 +0100 Subject: [PATCH] canvas: fix an integer overflow in caca_resize(). Fixes: #52 (CVE-2021-3410) --- caca/canvas.c | 13 +++++++++++-- caca/codec/import.c | 1 + caca/codec/text.c | 21 ++++++++++++++------- 3 files changed, 26 insertions(+), 9 deletions(-) diff --git a/caca/canvas.c b/caca/canvas.c index 3fdd37ae..d0715392 100644 --- a/caca/canvas.c +++ b/caca/canvas.c @@ -45,6 +45,7 @@ static int caca_resize(caca_canvas_t *, int, int); * * If an error occurs, NULL is returned and \b errno is set accordingly: * - \c EINVAL Specified width or height is invalid. + * - \c EOVERFLOW Specified width and height overflowed. * - \c ENOMEM Not enough memory for the requested canvas size. * * \param width The desired canvas width @@ -200,6 +201,7 @@ int caca_unmanage_canvas(caca_canvas_t *cv, int (*callback)(void *), void *p) * * If an error occurs, -1 is returned and \b errno is set accordingly: * - \c EINVAL Specified width or height is invalid. + * - \c EOVERFLOW Specified width and height overflowed. * - \c EBUSY The canvas is in use by a display driver and cannot be resized. * - \c ENOMEM Not enough memory for the requested canvas size. If this * happens, the canvas handle becomes invalid and should not be used. @@ -363,7 +365,7 @@ int caca_rand(int min, int max) int caca_resize(caca_canvas_t *cv, int width, int height) { - int x, y, f, old_width, old_height, new_size, old_size; + int x, y, f, old_width, old_height, old_size; old_width = cv->width; old_height = cv->height; @@ -375,7 +377,14 @@ int caca_resize(caca_canvas_t *cv, int width, int height) * dirty rectangle handling */ cv->width = width; cv->height = height; - new_size = width * height; + int new_size = width * height; + + /* Check for overflow */ + if (new_size / width != height) + { + seterrno(EOVERFLOW); + return -1; + } /* If width or height is smaller (or both), we have the opportunity to * reduce or even remove dirty rectangles */ diff --git a/caca/codec/import.c b/caca/codec/import.c index 8836fd08..2dafe3cf 100644 --- a/caca/codec/import.c +++ b/caca/codec/import.c @@ -61,6 +61,7 @@ static ssize_t import_caca(caca_canvas_t *, void const *, size_t); * * If an error occurs, -1 is returned and \b errno is set accordingly: * - \c ENOMEM Not enough memory to allocate canvas. + * - \c EOVERFLOW Importing data caused a value overflow. * - \c EINVAL Invalid format requested. * * \param cv A libcaca canvas in which to import the file. diff --git a/caca/codec/text.c b/caca/codec/text.c index 358b7224..94a2a4d7 100644 --- a/caca/codec/text.c +++ b/caca/codec/text.c @@ -46,7 +46,7 @@ ssize_t _import_text(caca_canvas_t *cv, void const *data, size_t size) char const *text = (char const *)data; unsigned int width = 0, height = 0, x = 0, y = 0, i; - caca_set_canvas_size(cv, width, height); + caca_set_canvas_size(cv, 0, 0); for(i = 0; i < size; i++) { @@ -70,15 +70,19 @@ ssize_t _import_text(caca_canvas_t *cv, void const *data, size_t size) if(y >= height) height = y + 1; - caca_set_canvas_size(cv, width, height); + if (caca_set_canvas_size(cv, width, height) < 0) + return -1; } caca_put_char(cv, x, y, ch); x++; } - if(y > height) - caca_set_canvas_size(cv, width, height = y); + if (y > height) + { + if (caca_set_canvas_size(cv, width, height = y) < 0) + return -1; + } return (ssize_t)size; } @@ -431,7 +435,8 @@ ssize_t _import_ansi(caca_canvas_t *cv, void const *data, size_t size, int utf8) { savedattr = caca_get_attr(cv, -1, -1); caca_set_attr(cv, im.clearattr); - caca_set_canvas_size(cv, width = x + wch, height); + if (caca_set_canvas_size(cv, width = x + wch, height) < 0) + return -1; caca_set_attr(cv, savedattr); } else @@ -448,7 +453,8 @@ ssize_t _import_ansi(caca_canvas_t *cv, void const *data, size_t size, int utf8) caca_set_attr(cv, im.clearattr); if(growy) { - caca_set_canvas_size(cv, width, height = y + 1); + if (caca_set_canvas_size(cv, width, height = y + 1) < 0) + return -1; } else { @@ -480,7 +486,8 @@ ssize_t _import_ansi(caca_canvas_t *cv, void const *data, size_t size, int utf8) { savedattr = caca_get_attr(cv, -1, -1); caca_set_attr(cv, im.clearattr); - caca_set_canvas_size(cv, width, height = y); + if (caca_set_canvas_size(cv, width, height = y)) + return -1; caca_set_attr(cv, savedattr); } iolation of this Code of Conduct: 1. Correction Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. 2. Warning Community Impact: A violation through a single incident or series of actions. Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. 3. Temporary Ban Community Impact: A serious violation of community standards, including sustained inappropriate behavior. Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. 4. Permanent Ban Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. Consequence: A permanent ban from any sort of public interaction within the community. Attribution This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. Community Impact Guidelines were inspired by Mozilla’s code of conduct enforcement ladder. For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.