diff options
author | Ingo Schwarze <schwarze@openbsd.org> | 2017-03-08 13:18:10 +0000 |
---|---|---|
committer | Ingo Schwarze <schwarze@openbsd.org> | 2017-03-08 13:18:10 +0000 |
commit | cc1572ad8c1416147be5842b72548f687cefd002 (patch) | |
tree | e6fdfc9550fb59f18edbd45c004872e03085e599 /roff.c | |
parent | 8ef8ebcf522a1fcfacc2601f9db3f97a55a3ddfd (diff) | |
download | mandoc-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.c | 19 |
1 files changed, 16 insertions, 3 deletions
@@ -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. */ |