summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorschwarze <schwarze@openbsd.org>2017-03-08 13:17:28 +0000
committerschwarze <schwarze@openbsd.org>2017-03-08 13:17:28 +0000
commite651e9badc00c639d67d497e80feb8b5acfaa84a (patch)
tree4844752c75eaae7295a0b102b554da2025cddf9c
parentquote [host]:port in generated ProxyJump commandline; the [ / ] (diff)
downloadwireguard-openbsd-e651e9badc00c639d67d497e80feb8b5acfaa84a.tar.xz
wireguard-openbsd-e651e9badc00c639d67d497e80feb8b5acfaa84a.zip
prevent infinite recursion while expanding the arguments
of a user-defined macro; issue found by tb@ with afl(1)
-rw-r--r--regress/usr.bin/mandoc/roff/de/infinite.in6
-rw-r--r--regress/usr.bin/mandoc/roff/de/infinite.out_ascii2
-rw-r--r--regress/usr.bin/mandoc/roff/de/infinite.out_lint1
-rw-r--r--usr.bin/mandoc/roff.c19
4 files changed, 24 insertions, 4 deletions
diff --git a/regress/usr.bin/mandoc/roff/de/infinite.in b/regress/usr.bin/mandoc/roff/de/infinite.in
index 683eba7f431..b6dac1f7769 100644
--- a/regress/usr.bin/mandoc/roff/de/infinite.in
+++ b/regress/usr.bin/mandoc/roff/de/infinite.in
@@ -7,6 +7,12 @@
.Sh DESCRIPTION
initial text
.de mym
+.Op \\$1 \\$2
+..
+.mym $1 \$1
+.mym \$1 nothing
+middle text
+.de mym
.mym
not printed
..
diff --git a/regress/usr.bin/mandoc/roff/de/infinite.out_ascii b/regress/usr.bin/mandoc/roff/de/infinite.out_ascii
index 7f8210ab6e3..17070a20475 100644
--- a/regress/usr.bin/mandoc/roff/de/infinite.out_ascii
+++ b/regress/usr.bin/mandoc/roff/de/infinite.out_ascii
@@ -4,6 +4,6 @@ NNAAMMEE
ddee--iinnffiinniittee - inifinte recursion in a user-defined macro
DDEESSCCRRIIPPTTIIOONN
- initial text final text
+ initial text [$1 $1] middle text final text
OpenBSD March 7, 2017 OpenBSD
diff --git a/regress/usr.bin/mandoc/roff/de/infinite.out_lint b/regress/usr.bin/mandoc/roff/de/infinite.out_lint
index 168c7be4ba5..7cea727c16d 100644
--- a/regress/usr.bin/mandoc/roff/de/infinite.out_lint
+++ b/regress/usr.bin/mandoc/roff/de/infinite.out_lint
@@ -1 +1,2 @@
mandoc: infinite.in:13:5: ERROR: input stack limit exceeded, infinite loop?
+mandoc: infinite.in:19:5: ERROR: input stack limit exceeded, infinite loop?
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c
index 94428d9d192..eebc31cdd7d 100644
--- a/usr.bin/mandoc/roff.c
+++ b/usr.bin/mandoc/roff.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: roff.c,v 1.163 2017/03/03 13:55:06 schwarze Exp $ */
+/* $OpenBSD: roff.c,v 1.164 2017/03/08 13:17:28 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -3036,7 +3036,7 @@ roff_userdef(ROFF_ARGS)
{
const char *arg[9], *ap;
char *cp, *n1, *n2;
- int i, ib, ie;
+ int expand_count, i, ib, ie;
size_t asz, rsz;
/*
@@ -3060,8 +3060,9 @@ roff_userdef(ROFF_ARGS)
*/
buf->sz = strlen(r->current_string) + 1;
- n1 = cp = mandoc_malloc(buf->sz);
+ n1 = n2 = cp = mandoc_malloc(buf->sz);
memcpy(n1, r->current_string, buf->sz);
+ expand_count = 0;
while (*cp != '\0') {
/* Scan ahead for the next argument invocation. */
@@ -3081,6 +3082,18 @@ roff_userdef(ROFF_ARGS)
cp -= 2;
/*
+ * Prevent infinite recursion.
+ */
+
+ if (cp >= n2)
+ expand_count = 1;
+ else if (++expand_count > EXPAND_LIMIT) {
+ mandoc_msg(MANDOCERR_ROFFLOOP, r->parse,
+ ln, (int)(cp - n1), NULL);
+ return ROFF_IGN;
+ }
+
+ /*
* Determine the size of the expanded argument,
* taking escaping of quotes into account.
*/