From nobody Wed Oct 14 16:04:14 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4j4bcG4tY2z6vmZX for ; Wed, 14 Oct 2026 16:04:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4j4bcG2y0kz4bGQ for ; Wed, 14 Oct 2026 16:04:14 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791993854; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LCgks2KoVGNd8CDbkOQUp9m8/P3sHWPQpPDJw43R7co=; b=xIJOE4gdSriRVkBmKleKzhAVrrKEtS2B9hE5kB4bwZtMQW454P0daaCDIdKOrYf/hzsTCC qKjTt53cgQIk4xNWD9FRK+WNx+fDKw4qkjXQXdFWEYCuL+coa+fPv889h6t4PeOf6rgfN8 aHQCCJwXJhGnFBeUe4xeZoAcuw7aI1sxCiCjAd2HMPQ9+tTt7XJ3AotsCvKHzmUASqtdFf dm7uhp5YlihJM+FxVBlzhnyrx8UftIMuJQBVCv3i6yM5IqqTqKN2jYUdBzN9MBpyBniAFL O9M2U2+J2/jRGR7cdTI9YkWPdxqTD79xCQ1JCZCJjl0c5ohMWasi4u6SmYWCFg== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791993854; b=gfjpi4Lu57sIYssMmYepDP572KPhFPNbdgvhaxh1lQX0mwbc2FPf9OtcrIwGXH8Bd1QghL 59LeX4T1FYOvGt+Sxwk//T0/qCAcyomOaRBY9EyyX+1ZlNVFZpyAVes0Yr8dLtisHKr1GI EipQlkZ9+S3EjD/7k8S+UHfRKhDJEQkbauGpBwg4PP+UAnmB5P0T9If8XNHWdPXyuGkR41 leb2m5aD8sbQ1Bql64JBUFK+Ejokd9l1VetBqH9yAzpa/uzxvanGv0L/CAa3ayIZSnVfM1 8jRHiBcjXn2SzKxro1oM7+36lNQy8urP4Z+IaMDEDRDFSIx3ykkC+FJkJLVXOA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791993854; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=LCgks2KoVGNd8CDbkOQUp9m8/P3sHWPQpPDJw43R7co=; b=u8amwTUkPtTnVn/vL712M9j3VXM2u24LfKi04JItnbuGoSH8kHG394GKqsfIDyXEfgoXf1 srTeBv3+URzRcRwJghQN6OtNoYqJpW/KNAPLpBe/0x9/uCWfpAo4wsxLqoKBHO9PwLvul8 mZnT360ktb2J6DKmjDASyVGpWfb75N9o4ovHhP3BWhj1Dd5tdIDHCGwZu5ogFNFQtQVqXb j+lnFmevG0K7eJ1FNkNIxFkouG2boTmghhVI59vcPIL0p38UmacfLwoETTOj1TEbW0n3cQ pSTzQ1bf3JnAd5+Z5moXn0bI/ZSdbhll270ZSRUkoBY9uMtkL9mHYLnqIRaefg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4j4bcG1y5Yz18Fh for ; Wed, 14 Oct 2026 16:04:14 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 26f5b by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Wed, 14 Oct 2026 16:04:14 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 2e4ec07874a2 - releng/14.5 - bhyve: Fix handling of framebuffer resizing List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: Commit messages for all branches of the src repository List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/releng/14.5 X-Git-Reftype: branch X-Git-Commit: 2e4ec07874a2fb1fd5de38eaf072a74fd8d5912c Auto-Submitted: auto-generated Date: Wed, 14 Oct 2026 16:04:14 +0000 Message-Id: <6acfa7fe.26f5b.62e7e762@gitrepo.freebsd.org> The branch releng/14.5 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=2e4ec07874a2fb1fd5de38eaf072a74fd8d5912c commit 2e4ec07874a2fb1fd5de38eaf072a74fd8d5912c Author: Mark Johnston AuthorDate: 2026-10-13 19:59:10 +0000 Commit: Mark Johnston CommitDate: 2026-10-13 23:17:33 +0000 bhyve: Fix handling of framebuffer resizing The rfb code maintains an array of CRCs for 32x32 tiles in the framebuffer. This array is sized statically based on the rfb code's notion of the maximum framebuffer size, which changed in commit fb51ddb20d57 without updating the rfb code. Morever, writes to the framebuffer BAR can modify the recorded height and width of the framebuffer. These values were not validated against the maximum at all, unlike the parameters set via bhyve config. Fix these problems: - Define the maximum width and height in a shared header file so that they do not get out of sync again. - In pci_fbuf_render(), don't resize the console if the new dimensions are too large. - Add a mutex to synchronize framebuffer BAR I/O with the rfb thread. Approved by: so Security: FreeBSD-SA-26:72.bhyve Security: CVE-2026-101311 Fixes: fb51ddb20d57 ("bhyve: increase fbuf display resolution limit") Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D60680 --- usr.sbin/bhyve/bhyvegc.h | 3 +++ usr.sbin/bhyve/pci_fbuf.c | 53 ++++++++++++++++++++++++++++++++--------------- usr.sbin/bhyve/rfb.c | 6 +++--- 3 files changed, 42 insertions(+), 20 deletions(-) diff --git a/usr.sbin/bhyve/bhyvegc.h b/usr.sbin/bhyve/bhyvegc.h index 5344473a05bd..57c4f048cacf 100644 --- a/usr.sbin/bhyve/bhyvegc.h +++ b/usr.sbin/bhyve/bhyvegc.h @@ -43,4 +43,7 @@ void bhyvegc_set_fbaddr(struct bhyvegc *gc, void *fbaddr); void bhyvegc_resize(struct bhyvegc *gc, int width, int height); struct bhyvegc_image *bhyvegc_get_image(struct bhyvegc *gc); +#define GC_COLS_MAX 1920 +#define GC_ROWS_MAX 1200 + #endif /* _BHYVEGC_H_ */ diff --git a/usr.sbin/bhyve/pci_fbuf.c b/usr.sbin/bhyve/pci_fbuf.c index e2d34cfef639..99e43a87e6c6 100644 --- a/usr.sbin/bhyve/pci_fbuf.c +++ b/usr.sbin/bhyve/pci_fbuf.c @@ -32,15 +32,16 @@ #include #include -#include +#include +#include #include #include #include - -#include #include +#include + #include "bhyvegc.h" #include "bhyverun.h" #include "config.h" @@ -72,9 +73,8 @@ static int fbuf_debug = 1; #define DMEMSZ 128 #define FB_SIZE (16*MB) - -#define COLS_MAX 1920 -#define ROWS_MAX 1200 +_Static_assert(FB_SIZE >= GC_ROWS_MAX * GC_COLS_MAX * sizeof(uint32_t), + "Framebuffer size is too small for maximum resolution"); #define COLS_DEFAULT 1024 #define ROWS_DEFAULT 768 @@ -93,6 +93,8 @@ struct pci_fbuf_softc { uint8_t reserved[116]; } __packed memregs; + pthread_mutex_t mtx; + /* rfb server */ char *rfb_host; char *rfb_password; @@ -134,8 +136,8 @@ pci_fbuf_write(struct pci_devinst *pi, int baridx, uint64_t offset, int size, return; } + pthread_mutex_lock(&sc->mtx); p = (uint8_t *)&sc->memregs + offset; - switch (size) { case 1: *p = value; @@ -165,6 +167,7 @@ pci_fbuf_write(struct pci_devinst *pi, int baridx, uint64_t offset, int size, DPRINTF(DEBUG_INFO, ("switching to VESA mode")); sc->gc_image->vgamode = 0; } + pthread_mutex_unlock(&sc->mtx); } static uint64_t @@ -178,13 +181,13 @@ pci_fbuf_read(struct pci_devinst *pi, int baridx, uint64_t offset, int size) sc = pi->pi_arg; - if (offset + size > DMEMSZ) { printf("fbuf: read too large, offset %ld size %d\n", offset, size); return (0); } + pthread_mutex_lock(&sc->mtx); p = (uint8_t *)&sc->memregs + offset; value = 0; switch (size) { @@ -204,6 +207,7 @@ pci_fbuf_read(struct pci_devinst *pi, int baridx, uint64_t offset, int size) printf("fbuf: read unknown size %d\n", size); break; } + pthread_mutex_unlock(&sc->mtx); DPRINTF(DEBUG_VERBOSE, ("fbuf rd: offset 0x%lx, size: %d, value: 0x%lx", @@ -316,7 +320,7 @@ pci_fbuf_parse_config(struct pci_fbuf_softc *sc, nvlist_t *nvl) value = get_config_value_node(nvl, "w"); if (value != NULL) { sc->memregs.width = atoi(value); - if (sc->memregs.width > COLS_MAX) { + if (sc->memregs.width > GC_COLS_MAX) { EPRINTLN("fbuf: width %d too large", sc->memregs.width); return (-1); } @@ -327,7 +331,7 @@ pci_fbuf_parse_config(struct pci_fbuf_softc *sc, nvlist_t *nvl) value = get_config_value_node(nvl, "h"); if (value != NULL) { sc->memregs.height = atoi(value); - if (sc->memregs.height > ROWS_MAX) { + if (sc->memregs.height > GC_ROWS_MAX) { EPRINTLN("fbuf: height %d too large", sc->memregs.height); return (-1); @@ -347,21 +351,32 @@ static void pci_fbuf_render(struct bhyvegc *gc, void *arg) { struct pci_fbuf_softc *sc; + uint32_t width, height; sc = arg; - + pthread_mutex_lock(&sc->mtx); if (sc->vga_full && sc->gc_image->vgamode) { /* TODO: mode switching to vga and vesa should use the special * EFI-bhyve protocol port. */ + pthread_mutex_unlock(&sc->mtx); vga_render(gc, sc->vgasc); return; } - if (sc->gc_width != sc->memregs.width || - sc->gc_height != sc->memregs.height) { - bhyvegc_resize(gc, sc->memregs.width, sc->memregs.height); - sc->gc_width = sc->memregs.width; - sc->gc_height = sc->memregs.height; + width = sc->memregs.width; + height = sc->memregs.height; + if (sc->gc_width != width || sc->gc_height != height) { + if (width > GC_COLS_MAX || height > GC_ROWS_MAX) { + /* Ignore an invalid resolution. */ + pthread_mutex_unlock(&sc->mtx); + } else { + sc->gc_width = width; + sc->gc_height = height; + pthread_mutex_unlock(&sc->mtx); + bhyvegc_resize(gc, width, height); + } + } else { + pthread_mutex_unlock(&sc->mtx); } } @@ -380,6 +395,8 @@ pci_fbuf_init(struct pci_devinst *pi, nvlist_t *nvl) pi->pi_arg = sc; + pthread_mutex_init(&sc->mtx, NULL); + /* initialize config space */ pci_set_cfgdata16(pi, PCIR_DEVICE, 0x40FB); pci_set_cfgdata16(pi, PCIR_VENDOR, 0xFB5D); @@ -438,8 +455,10 @@ pci_fbuf_init(struct pci_devinst *pi, nvlist_t *nvl) error = rfb_init(sc->rfb_host, sc->rfb_port, sc->rfb_wait, sc->rfb_password); done: - if (error) + if (error) { + pthread_mutex_destroy(&sc->mtx); free(sc); + } return (error); } diff --git a/usr.sbin/bhyve/rfb.c b/usr.sbin/bhyve/rfb.c index 0b4888483559..737dd197f285 100644 --- a/usr.sbin/bhyve/rfb.c +++ b/usr.sbin/bhyve/rfb.c @@ -192,9 +192,9 @@ struct rfb_pixfmt_msg { #define RFB_CLIENTMSG_EXT_KEYEVENT 0 -#define RFB_MAX_WIDTH 2000 -#define RFB_MAX_HEIGHT 1200 -#define RFB_ZLIB_BUFSZ RFB_MAX_WIDTH*RFB_MAX_HEIGHT*4 +#define RFB_MAX_WIDTH GC_COLS_MAX +#define RFB_MAX_HEIGHT GC_ROWS_MAX +#define RFB_ZLIB_BUFSZ (RFB_MAX_WIDTH * RFB_MAX_HEIGHT * 4) #define PIXEL_RED_SHIFT 16 #define PIXEL_GREEN_SHIFT 8