diff --git a/package/libvncserver/0002-add-bounds-checks-to-UltraZip-subrectangle-parsing.patch b/package/libvncserver/0002-add-bounds-checks-to-UltraZip-subrectangle-parsing.patch new file mode 100644 index 0000000000..fa4a7718cc --- /dev/null +++ b/package/libvncserver/0002-add-bounds-checks-to-UltraZip-subrectangle-parsing.patch @@ -0,0 +1,74 @@ +From 009008e2f4d5a54dd71f422070df3af7b3dbc931 Mon Sep 17 00:00:00 2001 +From: Kazuma Matsumoto <269371721+y637F9QQ2x@users.noreply.github.com> +Date: Sun, 22 Mar 2026 20:35:49 +0100 +Subject: [PATCH] libvncclient: add bounds checks to UltraZip subrectangle + parsing + +HandleUltraZipBPP() iterates over sub-rectangles using numCacheRects +(derived from the attacker-controlled rect.r.x) without validating +that the pointer stays within the decompressed data buffer. A malicious +server can set a large numCacheRects value, causing heap out-of-bounds +reads via the memcpy calls in the parsing loop. + +Add bounds checks before reading the 12-byte subrect header and before +advancing the pointer by the raw pixel data size. Use uint64_t for the +raw data size calculation to prevent integer overflow on 32-bit platforms. + +Upstream: https://github.com/LibVNC/libvncserver/commit/009008e2f4d5a54dd71f422070df3af7b3dbc931 +CVE: CVE-2026-32853 +Signed-off-by: Thomas Perale +--- + src/libvncclient/ultra.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/src/libvncclient/ultra.c b/src/libvncclient/ultra.c +index 1d3aaba6a..5633b8cbb 100644 +--- a/src/libvncclient/ultra.c ++++ b/src/libvncclient/ultra.c +@@ -126,6 +126,7 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) + int toRead=0; + int inflateResult=0; + unsigned char *ptr=NULL; ++ unsigned char *ptr_end=NULL; + lzo_uint uncompressedBytes = ry + (rw * 65535); + unsigned int numCacheRects = rx; + +@@ -194,11 +195,18 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) + + /* Put the uncompressed contents of the update on the screen. */ + ptr = (unsigned char *)client->raw_buffer; ++ ptr_end = ptr + uncompressedBytes; + for (i=0; i ptr_end) { ++ rfbClientLog("UltraZip: subrect %d header exceeds decompressed data bounds\n", i); ++ return FALSE; ++ } ++ + memcpy((char *)&sx, ptr, 2); ptr += 2; + memcpy((char *)&sy, ptr, 2); ptr += 2; + memcpy((char *)&sw, ptr, 2); ptr += 2; +@@ -213,8 +221,13 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) + + if (se == rfbEncodingRaw) + { ++ uint64_t rawBytes = (uint64_t)sw * sh * (BPP / 8); ++ if (rawBytes > (size_t)(ptr_end - ptr)) { ++ rfbClientLog("UltraZip: subrect %d raw data exceeds decompressed data bounds\n", i); ++ return FALSE; ++ } + client->GotBitmap(client, (unsigned char *)ptr, sx, sy, sw, sh); +- ptr += ((sw * sh) * (BPP / 8)); ++ ptr += (size_t)rawBytes; + } + } + +@@ -222,3 +235,4 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) + } + + #undef CARDBPP ++ diff --git a/package/libvncserver/0003-fix-NULL-pointer-dereferences-in-httpd-proxy-handlers.patch b/package/libvncserver/0003-fix-NULL-pointer-dereferences-in-httpd-proxy-handlers.patch new file mode 100644 index 0000000000..2d3ee45be8 --- /dev/null +++ b/package/libvncserver/0003-fix-NULL-pointer-dereferences-in-httpd-proxy-handlers.patch @@ -0,0 +1,64 @@ +From dc78dee51a7e270e537a541a17befdf2073f5314 Mon Sep 17 00:00:00 2001 +From: Kazuma Matsumoto <269371721+y637F9QQ2x@users.noreply.github.com> +Date: Thu, 19 Mar 2026 17:42:00 +0900 +Subject: [PATCH] libvncserver: fix NULL pointer dereferences in httpd proxy + handlers + +httpProcessInput() passes the return value of strchr() to atoi() +and strncmp() without checking for NULL. If a CONNECT request +contains no colon, or a GET request contains no slash, strchr() +returns NULL, leading to a segmentation fault. + +Add NULL checks before using the strchr() return values. + +CVE: CVE-2026-32854 +Upstream: https://github.com/LibVNC/libvncserver/commit/dc78dee51a7e270e537a541a17befdf2073f5314 +Signed-off-by: Thomas Perale +--- + src/libvncserver/httpd.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +diff --git a/src/libvncserver/httpd.c b/src/libvncserver/httpd.c +index f4fe51c9..7cefadc4 100644 +--- a/src/libvncserver/httpd.c ++++ b/src/libvncserver/httpd.c +@@ -337,10 +337,11 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen) + + + /* Process the request. */ +- if(rfbScreen->httpEnableProxyConnect) { ++if(rfbScreen->httpEnableProxyConnect) { + const static char* PROXY_OK_STR = "HTTP/1.0 200 OK\r\nContent-Type: octet-stream\r\nPragma: no-cache\r\n\r\n"; + if(!strncmp(buf, "CONNECT ", 8)) { +- if(atoi(strchr(buf, ':')+1)!=rfbScreen->port) { ++ char *colon = strchr(buf, ':'); ++ if(colon == NULL || atoi(colon+1)!=rfbScreen->port) { + rfbErr("httpd: CONNECT format invalid.\n"); + rfbWriteExact(&cl,INVALID_REQUEST_STR, strlen(INVALID_REQUEST_STR)); + httpCloseSock(rfbScreen); +@@ -353,14 +354,17 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen) + rfbScreen->httpSock = RFB_INVALID_SOCKET; + return; + } +- if (!strncmp(buf, "GET ",4) && !strncmp(strchr(buf,'/'),"/proxied.connection HTTP/1.", 27)) { +- /* proxy connection */ +- rfbLog("httpd: client asked for /proxied.connection\n"); +- rfbWriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR)); +- rfbNewClientConnection(rfbScreen,rfbScreen->httpSock); +- rfbScreen->httpSock = RFB_INVALID_SOCKET; +- return; +- } ++ if (!strncmp(buf, "GET ",4)) { ++ char *slash = strchr(buf, '/'); ++ if (slash != NULL && !strncmp(slash,"/proxied.connection HTTP/1.", 27)) { ++ /* proxy connection */ ++ rfbLog("httpd: client asked for /proxied.connection\n"); ++ rfbWriteExact(&cl,PROXY_OK_STR,strlen(PROXY_OK_STR)); ++ rfbNewClientConnection(rfbScreen,rfbScreen->httpSock); ++ rfbScreen->httpSock = RFB_INVALID_SOCKET; ++ return; ++ } ++ } + } + + if (strncmp(buf, "GET ", 4)) { diff --git a/package/libvncserver/libvncserver.mk b/package/libvncserver/libvncserver.mk index 1180fc8dc7..49c94b8708 100644 --- a/package/libvncserver/libvncserver.mk +++ b/package/libvncserver/libvncserver.mk @@ -13,6 +13,12 @@ LIBVNCSERVER_INSTALL_STAGING = YES LIBVNCSERVER_DEPENDENCIES = host-pkgconf lzo LIBVNCSERVER_CONF_OPTS = -DWITH_LZO=ON +# 0002-add-bounds-checks-to-UltraZip-subrectangle-parsing.patch +LIBVNCSERVER_IGNORE_CVES += CVE-2026-32853 + +# 0003-fix-NULL-pointer-dereferences-in-httpd-proxy-handlers.patch +LIBVNCSERVER_IGNORE_CVES += CVE-2026-32854 + # only used for examples LIBVNCSERVER_CONF_OPTS += \ -DWITH_FFMPEG=OFF \