File chafa-CVE-2022-2301.patch of Package chafa
Index: chafa-1.8.0/tools/chafa/xwd-loader.c
===================================================================
--- chafa-1.8.0.orig/tools/chafa/xwd-loader.c
+++ chafa-1.8.0/tools/chafa/xwd-loader.c
@@ -165,63 +165,86 @@ compute_pixel_type (XwdLoader *loader)
}
#define ASSERT_HEADER(x) if (!(x)) return FALSE
+#define UNPACK_FIELD_U32(dest, src, field) ((dest)->field = GUINT32_FROM_BE ((src)->field))
+#define UNPACK_FIELD_S32(dest, src, field) ((dest)->field = GINT32_FROM_BE ((src)->field))
static gboolean
-load_header (XwdLoader *loader) // gconstpointer in, gsize in_max_len, XwdHeader *header_out)
+load_header (XwdLoader *loader)
{
XwdHeader *h = &loader->header;
XwdHeader in;
- const guint32 *p = (const guint32 *) ∈
+ const XwdHeader *inp;
if (!file_mapping_taste (loader->mapping, &in, 0, sizeof (in)))
return FALSE;
- h->header_size = g_ntohl (*(p++));
- h->file_version = g_ntohl (*(p++));
- h->pixmap_format = g_ntohl (*(p++));
- h->pixmap_depth = g_ntohl (*(p++));
- h->pixmap_width = g_ntohl (*(p++));
- h->pixmap_height = g_ntohl (*(p++));
- h->x_offset = g_ntohl (*(p++));
- h->byte_order = g_ntohl (*(p++));
- h->bitmap_unit = g_ntohl (*(p++));
- h->bitmap_bit_order = g_ntohl (*(p++));
- h->bitmap_pad = g_ntohl (*(p++));
- h->bits_per_pixel = g_ntohl (*(p++));
- h->bytes_per_line = g_ntohl (*(p++));
- h->visual_class = g_ntohl (*(p++));
- h->red_mask = g_ntohl (*(p++));
- h->green_mask = g_ntohl (*(p++));
- h->blue_mask = g_ntohl (*(p++));
- h->bits_per_rgb = g_ntohl (*(p++));
- h->color_map_entries = g_ntohl (*(p++));
- h->n_colors = g_ntohl (*(p++));
- h->window_width = g_ntohl (*(p++));
- h->window_height = g_ntohl (*(p++));
- h->window_x = g_ntohl (*(p++));
- h->window_y = g_ntohl (*(p++));
- h->window_border_width = g_ntohl (*(p++));
+ inp = ∈
- /* Only support the most common/useful subset of XWD files out there;
- * namely, that corresponding to screen dumps from modern X.Org servers. */
+ UNPACK_FIELD_U32 (h, inp, header_size);
+ UNPACK_FIELD_U32 (h, inp, file_version);
+ UNPACK_FIELD_U32 (h, inp, pixmap_format);
+ UNPACK_FIELD_U32 (h, inp, pixmap_depth);
+ UNPACK_FIELD_U32 (h, inp, pixmap_width);
+ UNPACK_FIELD_U32 (h, inp, pixmap_height);
+ UNPACK_FIELD_U32 (h, inp, x_offset);
+ UNPACK_FIELD_U32 (h, inp, byte_order);
+ UNPACK_FIELD_U32 (h, inp, bitmap_unit);
+ UNPACK_FIELD_U32 (h, inp, bitmap_bit_order);
+ UNPACK_FIELD_U32 (h, inp, bitmap_pad);
+ UNPACK_FIELD_U32 (h, inp, bits_per_pixel);
+ UNPACK_FIELD_U32 (h, inp, bytes_per_line);
+ UNPACK_FIELD_U32 (h, inp, visual_class);
+ UNPACK_FIELD_U32 (h, inp, red_mask);
+ UNPACK_FIELD_U32 (h, inp, green_mask);
+ UNPACK_FIELD_U32 (h, inp, blue_mask);
+ UNPACK_FIELD_U32 (h, inp, bits_per_rgb);
+ UNPACK_FIELD_U32 (h, inp, color_map_entries);
+ UNPACK_FIELD_U32 (h, inp, n_colors);
+ UNPACK_FIELD_U32 (h, inp, window_width);
+ UNPACK_FIELD_U32 (h, inp, window_height);
+ UNPACK_FIELD_S32 (h, inp, window_x);
+ UNPACK_FIELD_S32 (h, inp, window_y);
+ UNPACK_FIELD_U32 (h, inp, window_border_width);
+
+ /* Only support the most common/useful subset of XWD files out there;
+ * namely, that corresponding to screen dumps from modern X.Org servers.
+ * namely, that corresponding to screen dumps from modern X.Org servers.
+ * We could check visual_class == 5 too, but the other fields convey all
+ * the info we need. */
ASSERT_HEADER (h->header_size >= sizeof (XwdHeader));
+ ASSERT_HEADER (h->header_size <= 65535);
ASSERT_HEADER (h->file_version == 7);
ASSERT_HEADER (h->pixmap_depth == 24);
ASSERT_HEADER (h->bits_per_rgb == 8);
ASSERT_HEADER (h->bytes_per_line >= h->pixmap_width * (h->bits_per_pixel / 8));
ASSERT_HEADER (compute_pixel_type (loader) < CHAFA_PIXEL_MAX);
+ /* Should be zero for truecolor/directcolor. Cap it to prevent overflows. */
+ ASSERT_HEADER (h->color_map_entries <= 256);
+
+ /* These are the pixel formats we allow. */
+ ASSERT_HEADER (h->bits_per_pixel == 24 || h->bits_per_pixel == 32);
+
+ /* Enforce sane dimensions. */
+ ASSERT_HEADER (h->pixmap_width >= 1 && h->pixmap_width <= 65535);
+ ASSERT_HEADER (h->pixmap_height >= 1 && h->pixmap_height <= 65535);
+
+ ASSERT_HEADER (h->bytes_per_line <= h->pixmap_width * (h->bits_per_pixel / 8) + 1024);
+
+ /* Make sure the total allocation/map is not too big. */
+ ASSERT_HEADER (h->bytes_per_line * h->pixmap_height < (1UL << 31) - 65536 - 256 * 32);
+
loader->file_data = file_mapping_get_data (loader->mapping, &loader->file_data_len);
if (!loader->file_data)
return FALSE;
ASSERT_HEADER (loader->file_data_len >= h->header_size
- + h->n_colors * sizeof (XwdColor)
- + h->pixmap_height * h->bytes_per_line);
+ + h->color_map_entries * sizeof (XwdColor)
+ + h->pixmap_height * (gsize) h->bytes_per_line);
loader->image_data = (const guint8 *) loader->file_data
- + h->header_size + h->n_colors * sizeof (XwdColor);
+ + h->header_size + h->color_map_entries * sizeof (XwdColor);
return TRUE;
}