summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2023-09-27 21:06:34 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2023-09-27 21:06:34 +0000
commitdba2bd80b11ec24bf0c99bf1a4adf004521b388d (patch)
tree76c51dfee2ca0e2659e92965204b71e267375894
parent1dc925b005c049a74c4bfe549113a18d2b028b37 (diff)
Use a dynamically-allocated line buffer and resize as needed.
Fixes a buffer overflow for lines over 2048 bytes. Problem reported by Crystal Kolipe. OK deraadt@
-rw-r--r--usr.bin/deroff/deroff.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/usr.bin/deroff/deroff.c b/usr.bin/deroff/deroff.c
index b4b560fa8d2..acb33b75051 100644
--- a/usr.bin/deroff/deroff.c
+++ b/usr.bin/deroff/deroff.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: deroff.c,v 1.17 2023/03/08 04:43:10 guenther Exp $ */
+/* $OpenBSD: deroff.c,v 1.18 2023/09/27 21:06:33 millert Exp $ */
/*-
* Copyright (c) 1988, 1993
@@ -135,7 +135,8 @@ int keepblock; /* keep blocks of text; normally false when msflag */
char chars[128]; /* SPECIAL, PUNCT, APOS, DIGIT, or LETTER */
-char line[LINE_MAX];
+size_t linesz;
+char *line;
char *lp;
int c;
@@ -342,6 +343,10 @@ main(int ac, char **av)
files[0] = infile;
filesp = &files[0];
+ linesz = LINE_MAX;
+ if ((line = malloc(linesz)) == NULL)
+ err(1, NULL);
+
for (i = 'a'; i <= 'z'; ++i)
chars[i] = LETTER;
for (i = 'A'; i <= 'Z'; ++i)
@@ -477,7 +482,15 @@ regline(void (*pfunc)(char *, int), int constant)
line[0] = c;
lp = line;
- while (lp - line < sizeof(line)) {
+ for (;;) {
+ if (lp - line == linesz - 1) {
+ char *newline = reallocarray(line, linesz, 2);
+ if (newline == NULL)
+ err(1, NULL);
+ lp = newline + (lp - line);
+ line = newline;
+ linesz *= 2;
+ }
if (c == '\\') {
*lp = ' ';
backsl();