Merge commit from fork
CVE-2026-41521: lib_framebuffer_update int overflow
This commit is contained in:
@@ -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,9 +1055,15 @@ 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))
|
||||||
!found &&
|
{
|
||||||
match(x, y, 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 &&
|
||||||
|
match(x, y, cx, cy))
|
||||||
{
|
{
|
||||||
LOG(LOG_LEVEL_DEBUG,
|
LOG(LOG_LEVEL_DEBUG,
|
||||||
"VNC_RESIZE: VNC matched ExtendedDesktopSize rectangle "
|
"VNC_RESIZE: VNC matched ExtendedDesktopSize rectangle "
|
||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user