git: 9cba21c2de16 - releng/14.3 - vt: Avoid integer overflow in CONS_HISTORY ioctl

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 09 Jun 2026 19:18:45 UTC
The branch releng/14.3 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=9cba21c2de1668717a77833ad1533416babe131a

commit 9cba21c2de1668717a77833ad1533416babe131a
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2026-05-26 16:19:47 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-06-07 17:48:17 +0000

    vt: Avoid integer overflow in CONS_HISTORY ioctl
    
    Approved by:    so
    Security:       FreeBSD-SA-26:34.vt
    Security:       CVE-2026-49416
    Reviewed by:    markj, vexeduxr
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D57250
    
    (cherry picked from commit 0ae946e7223df5ef3f7980af1d774d7f593f6421)
    (cherry picked from commit deaaddf1d3c4283649945553ad7e3208c8424308)
    (cherry picked from commit b5a4f4bfbc95d5d5361da708728f7f4a6db2ee60)
---
 sys/dev/vt/vt_buf.c  | 9 ++++-----
 sys/dev/vt/vt_core.c | 6 ++++--
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/sys/dev/vt/vt_buf.c b/sys/dev/vt/vt_buf.c
index ea27ea8a5ebf..0fd301bb662a 100644
--- a/sys/dev/vt/vt_buf.c
+++ b/sys/dev/vt/vt_buf.c
@@ -500,7 +500,6 @@ vtbuf_grow(struct vt_buf *vb, const term_pos_t *p, unsigned int history_size)
 {
 	term_char_t *old, *new, **rows, **oldrows, **copyrows, *row, *oldrow;
 	unsigned int w, h, c, r, old_history_size;
-	size_t bufsize, rowssize;
 	int history_full;
 	const teken_attr_t *a;
 	term_char_t ch;
@@ -511,10 +510,10 @@ vtbuf_grow(struct vt_buf *vb, const term_pos_t *p, unsigned int history_size)
 	history_size = MAX(history_size, p->tp_row);
 
 	/* Allocate new buffer. */
-	bufsize = history_size * p->tp_col * sizeof(term_char_t);
-	new = malloc(bufsize, M_VTBUF, M_WAITOK | M_ZERO);
-	rowssize = history_size * sizeof(term_pos_t *);
-	rows = malloc(rowssize, M_VTBUF, M_WAITOK | M_ZERO);
+	new = mallocarray(history_size, p->tp_col * sizeof(term_char_t),
+	    M_VTBUF, M_WAITOK | M_ZERO);
+	rows = mallocarray(history_size, sizeof(term_pos_t *), M_VTBUF,
+	    M_WAITOK | M_ZERO);
 
 	/* Toggle it. */
 	VTBUF_LOCK(vb);
diff --git a/sys/dev/vt/vt_core.c b/sys/dev/vt/vt_core.c
index 50f12512a81c..547bee8be86a 100644
--- a/sys/dev/vt/vt_core.c
+++ b/sys/dev/vt/vt_core.c
@@ -41,6 +41,7 @@
 #include <sys/kbio.h>
 #include <sys/kdb.h>
 #include <sys/kernel.h>
+#include <sys/limits.h>
 #include <sys/linker.h>
 #include <sys/lock.h>
 #include <sys/malloc.h>
@@ -2771,8 +2772,9 @@ skip_thunk:
 		/* XXX */
 		return (0);
 	case CONS_HISTORY:
-		if (*(int *)data < 0)
-			return EINVAL;
+		if (*(int *)data < 0 ||
+		    *(int *)data > UINT_MAX / USHRT_MAX / sizeof(term_char_t))
+			return (EINVAL);
 		if (*(int *)data != vw->vw_buf.vb_history_size)
 			vtbuf_sethistory_size(&vw->vw_buf, *(int *)data);
 		return (0);