Make sure we do not increase the escape sequence argument count beyond usable
authormiod <miod@openbsd.org>
Mon, 24 Jul 2023 17:03:32 +0000 (17:03 +0000)
committermiod <miod@openbsd.org>
Mon, 24 Jul 2023 17:03:32 +0000 (17:03 +0000)
bounds, in case escape sequences end up with too many semicolons.
Without this, the kernel could be made to access random memory after receiving
some specially crafted DCS or CSI terminal escape sequences.

Reported by David Leadbeater (dgl, dgl dot cx)

sys/dev/wscons/wsemul_sun.c
sys/dev/wscons/wsemul_vt100.c

index 40871af..e14c32d 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsemul_sun.c,v 1.36 2023/03/06 20:34:35 miod Exp $ */
+/* $OpenBSD: wsemul_sun.c,v 1.37 2023/07/24 17:03:32 miod Exp $ */
 /* $NetBSD: wsemul_sun.c,v 1.11 2000/01/05 11:19:36 drochner Exp $ */
 
 /*
@@ -617,13 +617,14 @@ wsemul_sun_output_control(struct wsemul_sun_emuldata *edp,
                break;
 
        case ';':               /* argument terminator */
-               edp->nargs++;
+               if (edp->nargs < SUN_EMUL_NARGS)
+                       edp->nargs++;
                break;
 
        default:                /* end of escape sequence */
-               oargs = edp->nargs++;
-               if (edp->nargs > SUN_EMUL_NARGS)
-                       edp->nargs = SUN_EMUL_NARGS;
+               oargs = edp->nargs;
+               if (edp->nargs < SUN_EMUL_NARGS)
+                       edp->nargs++;
                rc = wsemul_sun_control(edp, instate);
                if (rc != 0) {
                        /* undo nargs progress */
index 1f976bd..afea00b 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: wsemul_vt100.c,v 1.45 2023/03/06 20:34:35 miod Exp $ */
+/* $OpenBSD: wsemul_vt100.c,v 1.46 2023/07/24 17:03:32 miod Exp $ */
 /* $NetBSD: wsemul_vt100.c,v 1.13 2000/04/28 21:56:16 mycroft Exp $ */
 
 /*
@@ -868,16 +868,12 @@ wsemul_vt100_output_dcs(struct wsemul_vt100_emuldata *edp,
                    (instate->inchar - '0');
                break;
        case ';': /* argument terminator */
-               edp->nargs++;
+               if (edp->nargs < VT100_EMUL_NARGS)
+                       edp->nargs++;
                break;
        default:
-               edp->nargs++;
-               if (edp->nargs > VT100_EMUL_NARGS) {
-#ifdef VT100_DEBUG
-                       printf("vt100: too many arguments\n");
-#endif
-                       edp->nargs = VT100_EMUL_NARGS;
-               }
+               if (edp->nargs < VT100_EMUL_NARGS)
+                       edp->nargs++;
                newstate = VT100_EMUL_STATE_STRING;
                switch (instate->inchar) {
                case '$':
@@ -1069,7 +1065,8 @@ wsemul_vt100_output_csi(struct wsemul_vt100_emuldata *edp,
                    (instate->inchar - '0');
                break;
        case ';': /* argument terminator */
-               edp->nargs++;
+               if (edp->nargs < VT100_EMUL_NARGS)
+                       edp->nargs++;
                break;
        case '?': /* DEC specific */
        case '>': /* DA query */
@@ -1082,13 +1079,9 @@ wsemul_vt100_output_csi(struct wsemul_vt100_emuldata *edp,
                edp->modif2 = (char)instate->inchar;
                break;
        default: /* end of escape sequence */
-               oargs = edp->nargs++;
-               if (edp->nargs > VT100_EMUL_NARGS) {
-#ifdef VT100_DEBUG
-                       printf("vt100: too many arguments\n");
-#endif
-                       edp->nargs = VT100_EMUL_NARGS;
-               }
+               oargs = edp->nargs;
+               if (edp->nargs < VT100_EMUL_NARGS)
+                       edp->nargs++;
                rc = wsemul_vt100_handle_csi(edp, instate);
                if (rc != 0) {
                        edp->nargs = oargs;