aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/roff.c
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-03-08 13:18:10 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-03-08 13:18:10 +0000
commitcc1572ad8c1416147be5842b72548f687cefd002 (patch)
treee6fdfc9550fb59f18edbd45c004872e03085e599 /roff.c
parent8ef8ebcf522a1fcfacc2601f9db3f97a55a3ddfd (diff)
downloadmandoc-cc1572ad8c1416147be5842b72548f687cefd002.tar.gz
mandoc-cc1572ad8c1416147be5842b72548f687cefd002.tar.zst
mandoc-cc1572ad8c1416147be5842b72548f687cefd002.zip
prevent infinite recursion while expanding the arguments
of a user-defined macro; issue found by tb@ with afl(1)
Diffstat (limited to 'roff.c')
-rw-r--r--roff.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/roff.c b/roff.c
index d91c9c2b..cf9a1baa 100644
--- a/roff.c
+++ b/roff.c
@@ -1,4 +1,4 @@
-/* $Id: roff.c,v 1.291 2017/03/03 13:55:32 schwarze Exp $ */
+/* $Id: roff.c,v 1.292 2017/03/08 13:18:10 schwarze Exp $ */
/*
* Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
* Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org>
@@ -3038,7 +3038,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;
/*
@@ -3062,8 +3062,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. */
@@ -3083,6 +3084,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.
*/