Avoid one-byte overflow in error path. If the format string ends in an
authortb <tb@openbsd.org>
Sat, 30 Dec 2017 07:19:05 +0000 (07:19 +0000)
committertb <tb@openbsd.org>
Sat, 30 Dec 2017 07:19:05 +0000 (07:19 +0000)
invalid specifier like `%l', p will already point to the trailing NUL
upon entering the switch, wherein the instruction

*++p = '\0';

will write another NUL after it, but there is no guarantee that the
buffer extends beyond that first NUL; thus, in the rare case where it
does not, this assignment will write one byte past its end.

from kshe

usr.bin/jot/jot.c

index 12b1fc5..8e07223 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: jot.c,v 1.39 2017/12/15 14:20:52 tb Exp $     */
+/*     $OpenBSD: jot.c,v 1.40 2017/12/30 07:19:05 tb Exp $     */
 /*     $NetBSD: jot.c,v 1.3 1994/12/02 20:29:43 pk Exp $       */
 
 /*-
@@ -406,8 +406,7 @@ getformat(void)
                if (*p == 'l') {
                        longdata = true;
                        if (*++p == 'l') {
-                               if (p[1] != '\0')
-                                       p++;
+                               p++;
                                goto fmt_broken;
                        }
                }
@@ -449,7 +448,8 @@ getformat(void)
                        /* FALLTHROUGH */
                default:
 fmt_broken:
-                       *++p = '\0';
+                       if (*p != '\0')
+                               p[1] = '\0';
                        errx(1, "illegal or unsupported format '%s'", p2);
                }
                while (*++p != '\0')