Control: tags -1 + patch

Hi,

On Sun, Feb 28, 2021 at 01:54:37PM +0100, Salvatore Bonaccorso wrote:
> Source: libcaca
> Version: 0.99.beta19-2.1
> Severity: important
> Tags: security upstream
> Forwarded: https://github.com/cacalabs/libcaca/issues/52
> X-Debbugs-Cc: car...@debian.org, Debian Security Team 
> <t...@security.debian.org>
> 
> Hi,
> 
> The following vulnerability was published for libcaca.
> 
> CVE-2021-3410[0]:
> | A flaw was found in libcaca v0.99.beta19. A buffer overflow issue in
> | caca_resize function in libcaca/caca/canvas.c may lead to local
> | execution of arbitrary code in the user context.
> 
> 
> If you fix the vulnerability please also make sure to include the
> CVE (Common Vulnerabilities & Exposures) id in your changelog entry.
> 
> For further information see:
> 
> [0] https://security-tracker.debian.org/tracker/CVE-2021-3410
>     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-3410
> [1] https://github.com/cacalabs/libcaca/issues/52

Attached is debdiff prepared (not yet uploaded).

Regards,
Salvatore
diff -Nru libcaca-0.99.beta19/debian/changelog 
libcaca-0.99.beta19/debian/changelog
--- libcaca-0.99.beta19/debian/changelog        2019-04-06 22:18:41.000000000 
+0200
+++ libcaca-0.99.beta19/debian/changelog        2021-03-10 14:59:27.000000000 
+0100
@@ -1,3 +1,14 @@
+libcaca (0.99.beta19-2.2) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * Illegal write memory access in caca_resize function (CVE-2021-3410)
+    - canvas: fix an integer overflow in caca_resize().
+    - Fix a problem in the caca_resize() overflow detection and add
+      several unit tests
+    (Closes: #983686)
+
+ -- Salvatore Bonaccorso <car...@debian.org>  Wed, 10 Mar 2021 14:59:27 +0100
+
 libcaca (0.99.beta19-2.1) unstable; urgency=medium
 
   * Non-maintainer upload.
diff -Nru 
libcaca-0.99.beta19/debian/patches/Fix-a-problem-in-the-caca_resize-overflow-detection-.patch
 
libcaca-0.99.beta19/debian/patches/Fix-a-problem-in-the-caca_resize-overflow-detection-.patch
--- 
libcaca-0.99.beta19/debian/patches/Fix-a-problem-in-the-caca_resize-overflow-detection-.patch
       1970-01-01 01:00:00.000000000 +0100
+++ 
libcaca-0.99.beta19/debian/patches/Fix-a-problem-in-the-caca_resize-overflow-detection-.patch
       2021-03-10 14:59:27.000000000 +0100
@@ -0,0 +1,135 @@
+From: Sam Hocevar <s...@hocevar.net>
+Date: Fri, 26 Feb 2021 12:40:06 +0100
+Subject: [2/2] Fix a problem in the caca_resize() overflow detection and add
+ several unit tests.
+Origin: 
https://github.com/cacalabs/libcaca/commit/e4968ba6e93e9fd35429eb16895c785c51072015
+Bug: https://github.com/cacalabs/libcaca/issues/52
+Bug-Debian: https://bugs.debian.org/983686
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-3410
+
+---
+ caca/canvas.c     | 16 ++++++++--------
+ test/canvas.cpp   | 18 +++++++++++++++---
+ tools/makefont.c  | 22 +++++++++++++++++++---
+ 3 files changed, 42 insertions(+), 14 deletions(-)
+
+--- a/caca/canvas.c
++++ b/caca/canvas.c
+@@ -367,6 +367,14 @@ int caca_resize(caca_canvas_t *cv, int w
+ {
+     int x, y, f, old_width, old_height, old_size;
+ 
++    /* Check for overflow */
++    int new_size = width * height;
++    if (new_size < 0 || (width > 0 && new_size / width != height))
++    {
++        seterrno(EOVERFLOW);
++        return -1;
++    }
++
+     old_width = cv->width;
+     old_height = cv->height;
+     old_size = old_width * old_height;
+@@ -377,14 +385,6 @@ int caca_resize(caca_canvas_t *cv, int w
+      * dirty rectangle handling */
+     cv->width = width;
+     cv->height = 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 */
+--- a/test/canvas.cpp
++++ b/test/canvas.cpp
+@@ -16,6 +16,7 @@
+ #include <cppunit/TestCaller.h>
+ #include <cppunit/TestCase.h>
+ #include <cppunit/TestSuite.h>
++#include <climits>
+ 
+ #include "caca.h"
+ 
+@@ -53,18 +54,29 @@ public:
+         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_width(cv), 0);
+         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_height(cv), 0);
+ 
+-        caca_set_canvas_size(cv, 1, 1);
++        int ret = caca_set_canvas_size(cv, 1, 1);
++        CPPUNIT_ASSERT_EQUAL(ret, 0);
+         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_width(cv), 1);
+         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_height(cv), 1);
+ 
+-        caca_set_canvas_size(cv, 1234, 1001);
++        ret = caca_set_canvas_size(cv, 1234, 1001);
++        CPPUNIT_ASSERT_EQUAL(ret, 0);
+         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_width(cv), 1234);
+         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_height(cv), 1001);
+ 
+-        caca_set_canvas_size(cv, 0, 0);
++        ret = caca_set_canvas_size(cv, 0, 0);
++        CPPUNIT_ASSERT_EQUAL(ret, 0);
+         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_width(cv), 0);
+         CPPUNIT_ASSERT_EQUAL(caca_get_canvas_height(cv), 0);
+ 
++        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, -1, 50));
++        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, 50, -1));
++        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, -1, -1));
++        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, INT_MAX / 2, 3));
++        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, 3, INT_MAX / 2));
++        CPPUNIT_ASSERT_EQUAL(-1, caca_set_canvas_size(cv, INT_MAX / 2, 
INT_MAX / 2));
++        CPPUNIT_ASSERT_EQUAL(0, caca_set_canvas_size(cv, 0, 0));
++
+         caca_free_canvas(cv);
+     }
+ 
+--- a/tools/makefont.c
++++ b/tools/makefont.c
+@@ -40,7 +40,8 @@
+  * and the UTF-8 glyphs necessary for canvas rotation and mirroring. */
+ static unsigned int const blocklist[] =
+ {
+-    0x0000, 0x0080, /* Basic latin: A, B, C, a, b, c */
++    0x0020, 0x0080, /* Basic latin: A, B, C, a, b, c */
++#if 0
+     0x0080, 0x0100, /* Latin-1 Supplement: Ä, Ç, å, ß */
+     0x0100, 0x0180, /* Latin Extended-A: Ā č Ō œ */
+     0x0180, 0x0250, /* Latin Extended-B: Ǝ Ƹ */
+@@ -63,6 +64,7 @@ static unsigned int const blocklist[] =
+     0x30a0, 0x3100, /* Katakana: ロ ル */
+     0xff00, 0xfff0, /* Halfwidth and Fullwidth Forms: A, B, C, a, b, c */
+     0x10400, 0x10450, /* Deseret: 𐐒 𐐋 */
++#endif
+     0, 0
+ };
+ 
+@@ -317,8 +319,22 @@ int main(int argc, char *argv[])
+             printf_unicode(&gtab[n]);
+ 
+             if(gtab[n].same_as == n)
+-                printf_hex(" */ %s\n",
+-                           glyph_data + gtab[n].data_offset, 
gtab[n].data_size);
++            {
++                char const *lut = " .:nmW@";
++                printf("\n");
++                for (int y = 0; y < height; ++y)
++                {
++                    for (int x = 0; x < gtab[n].data_width; ++x)
++                    {
++                        int val = glyph_data[gtab[n].data_offset + y * 
gtab[n].data_width + x];
++                        char ch = lut[val * val * 7 / 256 / 256];
++                        printf("%c%c", ch, ch);
++                    }
++                    printf("\n");
++                }
++                //printf_hex(" */ %s\n",
++                //           glyph_data + gtab[n].data_offset, 
gtab[n].data_size);
++            }
+             else
+             {
+                 printf(" is ");
diff -Nru 
libcaca-0.99.beta19/debian/patches/canvas-fix-an-integer-overflow-in-caca_resize.patch
 
libcaca-0.99.beta19/debian/patches/canvas-fix-an-integer-overflow-in-caca_resize.patch
--- 
libcaca-0.99.beta19/debian/patches/canvas-fix-an-integer-overflow-in-caca_resize.patch
      1970-01-01 01:00:00.000000000 +0100
+++ 
libcaca-0.99.beta19/debian/patches/canvas-fix-an-integer-overflow-in-caca_resize.patch
      2021-03-10 14:59:27.000000000 +0100
@@ -0,0 +1,141 @@
+From: Sam Hocevar <s...@hocevar.net>
+Date: Fri, 26 Feb 2021 10:55:38 +0100
+Subject: [1/2] canvas: fix an integer overflow in caca_resize().
+Origin: 
https://github.com/cacalabs/libcaca/commit/46b4ea7cea72d6b3ffe65d33e604b1774dcc2bbd
+Bug: https://github.com/cacalabs/libcaca/issues/52
+Bug-Debian: https://bugs.debian.org/983686
+Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2021-3410
+
+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 3fdd37ae8ef9..d07153926c3a 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 8836fd0893e3..2dafe3cf97c1 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 358b7224fe87..94a2a4d7bcdb 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);
+     }
+ 
+-- 
+2.30.0
+
diff -Nru libcaca-0.99.beta19/debian/patches/series 
libcaca-0.99.beta19/debian/patches/series
--- libcaca-0.99.beta19/debian/patches/series   2019-04-06 21:46:52.000000000 
+0200
+++ libcaca-0.99.beta19/debian/patches/series   2021-03-10 14:59:27.000000000 
+0100
@@ -3,3 +3,5 @@
 CVE-2018-20544.patch
 CVE-2018-20545+20547+20549.patch
 CVE-2018-20546+20547.patch
+canvas-fix-an-integer-overflow-in-caca_resize.patch
+Fix-a-problem-in-the-caca_resize-overflow-detection-.patch

Reply via email to