Merge commit from fork

CVE-2026-41521: lib_framebuffer_update int overflow
This commit is contained in:
metalefty
2026-07-02 17:24:29 +09:00
committed by GitHub
+33 -2
View File
@@ -978,6 +978,25 @@ skip_encoding(struct vnc *v, int x, int y, int cx, int cy,
return error; return error;
} }
/**************************************************************************//**
* Checks the size parameters from a framebuffer update are sane
* @param cx Width of update
* @param cy height of update
* @return 0 if the proposed sizes could result in overflow
*
* [MS-RDPBCGR] allows for a max desktop size of
* CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_WIDTH x
* CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_HEIGHT
* Each pixel needs up to 4 bytes
*/
static int
framebuffer_update_size_ok(int cx, int cy)
{
return (cx <= CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_WIDTH &&
cy <= CLIENT_MONITOR_DATA_MAXIMUM_VIRTUAL_DESKTOP_HEIGHT &&
(cx * cy) <= (INT_MAX / 4));
}
/**************************************************************************//** /**************************************************************************//**
* Parses an entire framebuffer update message from the wire, and returns the * Parses an entire framebuffer update message from the wire, and returns the
* first matching ExtendedDesktopSize encoding if found. * first matching ExtendedDesktopSize encoding if found.
@@ -1036,7 +1055,13 @@ find_matching_extended_rect(struct vnc *v,
in_uint16_be(s, cy); in_uint16_be(s, cy);
in_uint32_be(s, encoding); in_uint32_be(s, encoding);
if (encoding == RFB_ENC_EXTENDED_DESKTOP_SIZE && if (!framebuffer_update_size_ok(cx, cy))
{
LOG(LOG_LEVEL_ERROR,
"find_matching_extended_rect: Frame buffer too large");
error = 1;
}
else if (encoding == RFB_ENC_EXTENDED_DESKTOP_SIZE &&
!found && !found &&
match(x, y, cx, cy)) match(x, y, cx, cy))
{ {
@@ -1467,7 +1492,13 @@ lib_framebuffer_update(struct vnc *v)
in_uint16_be(s, cy); in_uint16_be(s, cy);
in_uint32_be(s, encoding); in_uint32_be(s, encoding);
if (encoding == RFB_ENC_RAW) if (!framebuffer_update_size_ok(cx, cy))
{
LOG(LOG_LEVEL_ERROR,
"lib_framebuffer_update: Frame buffer too large");
error = 1;
}
else if (encoding == RFB_ENC_RAW)
{ {
need_size = cx * cy * get_bytes_per_pixel(v->server_bpp); need_size = cx * cy * get_bytes_per_pixel(v->server_bpp);
init_stream(pixel_s, need_size); init_stream(pixel_s, need_size);