summary refs log tree commit diff
path: root/gnu/packages/patches/libcaca-CVE-2021-3410-pt1.patch
blob: b23b01d33ab2ed0d168f9ceb154cb091a1b1cc3a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
https://github.com/cacalabs/libcaca/commit/46b4ea7cea72d6b3ffe65d33e604b1774dcc2bbd.patch

From 46b4ea7cea72d6b3ffe65d33e604b1774dcc2bbd Mon Sep 17 00:00:00 2001
From: Sam Hocevar <sam@hocevar.net>
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);
     }