Reduce memory and time consumption on certain malformed input files
authorschwarze <schwarze@openbsd.org>
Thu, 25 Dec 2014 17:18:40 +0000 (17:18 +0000)
committerschwarze <schwarze@openbsd.org>
Thu, 25 Dec 2014 17:18:40 +0000 (17:18 +0000)
by limiting the length of expanded input lines during the
(usually recursive) expansion of user defined strings.
Resource hogging found by jsg@ with afl.

share/man/man7/roff.7
usr.bin/mandoc/roff.c

index 9222fe4..c682582 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: roff.7,v 1.39 2014/12/02 10:07:17 schwarze Exp $
+.\"    $OpenBSD: roff.7,v 1.40 2014/12/25 17:18:40 schwarze Exp $
 .\"
 .\" Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
 .\" Copyright (c) 2010, 2011, 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,7 +15,7 @@
 .\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 .\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 .\"
-.Dd $Mdocdate: December 2 2014 $
+.Dd $Mdocdate: December 25 2014 $
 .Dt ROFF 7
 .Os
 .Sh NAME
@@ -541,8 +541,10 @@ one explicit newline character.
 In order to prevent endless recursion, both groff and
 .Xr mandoc 1
 limit the stack depth for expanding macros and strings
-to a large, but finite number.
-Do not rely on the exact value of this limit.
+to a large, but finite number, and
+.Xr mandoc 1
+also limits the length of the expanded input line.
+Do not rely on the exact values of these limits.
 .Ss \&dei
 Define a
 .Nm
index edd8b40..7d6a02e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: roff.c,v 1.116 2014/12/18 17:43:07 schwarze Exp $ */
+/*     $OpenBSD: roff.c,v 1.117 2014/12/25 17:18:40 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011, 2012 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2010-2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -19,6 +19,7 @@
 
 #include <assert.h>
 #include <ctype.h>
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -656,6 +657,12 @@ roff_res(struct roff *r, struct buf *buf, int ln, int pos)
                buf->sz = mandoc_asprintf(&nbuf, "%s%s%s",
                    buf->buf, res, cp) + 1;
 
+               if (buf->sz > SHRT_MAX) {
+                       mandoc_msg(MANDOCERR_ROFFLOOP, r->parse,
+                           ln, (int)(stesc - buf->buf), NULL);
+                       return(ROFF_IGN);
+               }
+
                /* Prepare for the next replacement. */
 
                start = nbuf + pos;