diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2023-09-27 21:06:34 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2023-09-27 21:06:34 +0000 |
commit | dba2bd80b11ec24bf0c99bf1a4adf004521b388d (patch) | |
tree | 76c51dfee2ca0e2659e92965204b71e267375894 | |
parent | 1dc925b005c049a74c4bfe549113a18d2b028b37 (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.c | 19 |
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(); |