aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2018-11-06 14:40:41 +0100
committeremersion <contact@emersion.fr>2018-11-06 14:40:41 +0100
commitde0a032d8ebd05999a702f304b7eb58ea189f14a (patch)
tree96fd3640a9c26ee571688990305eb2de35b136a7
parent2bf482e90f04dd7e402b37cb1d6c4d7fa958887c (diff)
xcursor: Fix heap overflows when parsing malicious files
It is possible to trigger heap overflows due to an integer overflow while parsing images. The integer overflow occurs because the chosen limit 0x10000 for dimensions is too large for 32 bit systems, because each pixel takes 4 bytes. Properly chosen values allow an overflow which in turn will lead to less allocated memory than needed for subsequent reads. See also: https://cgit.freedesktop.org/xorg/lib/libXcursor/commit/?id=4794b5dd34688158fb51a2943032569d3780c4b8 https://gitlab.freedesktop.org/wayland/wayland/commit/5d201df72f3d4f4cb8b8f75f980169b03507da38
-rw-r--r--xcursor/xcursor.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/xcursor/xcursor.c b/xcursor/xcursor.c
index 32711105..6690da1a 100644
--- a/xcursor/xcursor.c
+++ b/xcursor/xcursor.c
@@ -203,6 +203,11 @@ XcursorImageCreate (int width, int height)
{
XcursorImage *image;
+ if (width < 0 || height < 0)
+ return NULL;
+ if (width > XCURSOR_IMAGE_MAX_SIZE || height > XCURSOR_IMAGE_MAX_SIZE)
+ return NULL;
+
image = malloc (sizeof (XcursorImage) +
width * height * sizeof (XcursorPixel));
if (!image)
@@ -483,7 +488,8 @@ _XcursorReadImage (XcursorFile *file,
if (!_XcursorReadUInt (file, &head.delay))
return NULL;
/* sanity check data */
- if (head.width >= 0x10000 || head.height > 0x10000)
+ if (head.width > XCURSOR_IMAGE_MAX_SIZE ||
+ head.height > XCURSOR_IMAGE_MAX_SIZE)
return NULL;
if (head.width == 0 || head.height == 0)
return NULL;
@@ -877,9 +883,11 @@ load_all_cursors_from_dir(const char *path, int size,
return;
for(ent = readdir(dir); ent; ent = readdir(dir)) {
+#ifdef _DIRENT_HAVE_D_TYPE
if (ent->d_type != DT_UNKNOWN &&
(ent->d_type != DT_REG && ent->d_type != DT_LNK))
continue;
+#endif
full = _XcursorBuildFullname(path, "", ent->d_name);
if (!full)