untrusted comment: verify with openbsd-71-base.pub RWR2eHwZTOEiTQsySzqxaKpFvJU/0Nl2CtHti5LQ9ONkKLOJMjHlrz4lqHZkBsRvvYY+MYVUxqSK9OkDN6Z8lXcmvGjMz8PHYgA= OpenBSD 7.1 errata 025, February 26, 2023: Missing bounds check in console terminal emulation could cause a kernel crash after receiving specially crafted escape sequences. Apply by doing: signify -Vep /etc/signify/openbsd-71-base.pub -x 025_wscons.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install a new kernel: KK=`sysctl -n kern.osversion | cut -d# -f1` cd /usr/src/sys/arch/`machine`/compile/$KK make obj make config make make install Index: sys/dev/wscons/wsemul_vt100.c =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsemul_vt100.c,v diff -u -p -u -r1.39 wsemul_vt100.c --- sys/dev/wscons/wsemul_vt100.c 25 May 2020 09:55:49 -0000 1.39 +++ sys/dev/wscons/wsemul_vt100.c 23 Feb 2023 17:54:34 -0000 @@ -189,7 +189,7 @@ wsemul_vt100_cnattach(const struct wsscr edp->tabs = NULL; edp->dblwid = NULL; edp->dw = 0; - edp->dcsarg = 0; + edp->dcsarg = NULL; edp->isolatin1tab = edp->decgraphtab = edp->dectechtab = NULL; edp->nrctab = NULL; wsemul_vt100_reset(edp); @@ -574,12 +574,15 @@ wsemul_vt100_output_esc(struct wsemul_vt edp->sschartab = 3; break; case 'M': /* RI */ - if (ROWS_ABOVE > 0) { - edp->crow--; + i = ROWS_ABOVE; + if (i > 0) { + if (edp->crow > 0) + edp->crow--; CHECK_DW; - break; + } else if (i == 0) { + /* Top of scroll region. */ + rc = wsemul_vt100_scrolldown(edp, 1); } - rc = wsemul_vt100_scrolldown(edp, 1); break; case 'P': /* DCS */ edp->nargs = 0; @@ -807,7 +810,7 @@ int wsemul_vt100_output_string(struct wsemul_vt100_emuldata *edp, struct wsemul_inputstate *instate) { - if (edp->dcstype && edp->dcspos < DCS_MAXLEN) { + if (edp->dcsarg && edp->dcstype && edp->dcspos < DCS_MAXLEN) { if (instate->inchar & ~0xff) { #ifdef VT100_PRINTUNKNOWN printf("unknown char %x in DCS\n", instate->inchar); Index: sys/dev/wscons/wsemul_vt100_subr.c =================================================================== RCS file: /cvs/src/sys/dev/wscons/wsemul_vt100_subr.c,v diff -u -p -u -r1.24 wsemul_vt100_subr.c --- sys/dev/wscons/wsemul_vt100_subr.c 25 May 2020 09:55:49 -0000 1.24 +++ sys/dev/wscons/wsemul_vt100_subr.c 23 Feb 2023 17:54:34 -0000 @@ -447,11 +447,15 @@ wsemul_vt100_handle_csi(struct wsemul_vt ERASECOLS(edp->ccol, n, edp->bkgdattr)); break; case 'A': /* CUU */ - edp->crow -= min(DEF1_ARG(0), ROWS_ABOVE); + n = ROWS_ABOVE; + if (n > 0) + edp->crow -= min(DEF1_ARG(0), n); CHECK_DW; break; case 'B': /* CUD */ - edp->crow += min(DEF1_ARG(0), ROWS_BELOW); + n = ROWS_BELOW; + if (n > 0) + edp->crow += min(DEF1_ARG(0), n); CHECK_DW; break; case 'C': /* CUF */ @@ -474,21 +478,22 @@ wsemul_vt100_handle_csi(struct wsemul_vt break; case 'L': /* IL insert line */ case 'M': /* DL delete line */ - { - int savscrstartrow, savscrnrows; + if (edp->crow >= edp->scrreg_startrow && + edp->crow < edp->scrreg_startrow + edp->scrreg_nrows) { + int savscrstartrow, savscrnrows; - n = min(DEF1_ARG(0), ROWS_BELOW + 1); - savscrstartrow = edp->scrreg_startrow; - savscrnrows = edp->scrreg_nrows; - edp->scrreg_nrows -= ROWS_ABOVE; - edp->scrreg_startrow = edp->crow; - if (c == 'L') - rc = wsemul_vt100_scrolldown(edp, n); - else - rc = wsemul_vt100_scrollup(edp, n); - edp->scrreg_startrow = savscrstartrow; - edp->scrreg_nrows = savscrnrows; - } + n = min(DEF1_ARG(0), ROWS_BELOW + 1); + savscrstartrow = edp->scrreg_startrow; + savscrnrows = edp->scrreg_nrows; + edp->scrreg_nrows -= ROWS_ABOVE; + edp->scrreg_startrow = edp->crow; + if (c == 'L') + rc = wsemul_vt100_scrolldown(edp, n); + else + rc = wsemul_vt100_scrollup(edp, n); + edp->scrreg_startrow = savscrstartrow; + edp->scrreg_nrows = savscrnrows; + } /* else not within scrolling region, ignore the sequence */ break; case 'P': /* DCH delete character */ n = min(DEF1_ARG(0), COLS_LEFT + 1); @@ -625,9 +630,11 @@ wsemul_vt100_handle_csi(struct wsemul_vt { char buf[20]; int row; - if (edp->flags & VTFL_DECOM) + if (edp->flags & VTFL_DECOM) { row = ROWS_ABOVE; - else + if (row < 0) + row = 0; + } else row = edp->crow; n = snprintf(buf, sizeof buf, "\033[%d;%dR", row + 1, edp->ccol + 1); @@ -788,13 +795,17 @@ wsemul_vt100_handle_dcs(struct wsemul_vt if (edp->tabs != NULL) { memset(edp->tabs, 0, edp->ncols); pos = 0; + if (edp->dcsarg == NULL) + goto out; for (i = 0; i < edp->dcspos; i++) { char c = edp->dcsarg[i]; switch (c) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - pos = pos * 10 + (edp->dcsarg[i] - '0'); + pos = pos * 10 + (c - '0'); + if (pos > edp->ncols) + goto out; break; case '/': if (pos > 0) @@ -818,6 +829,7 @@ wsemul_vt100_handle_dcs(struct wsemul_vt #endif break; } +out: edp->dcstype = 0; }