From 9327b4212797c88b816c2566085d224b3826cf4c Mon Sep 17 00:00:00 2001 From: schwarze Date: Wed, 24 Dec 2014 09:57:41 +0000 Subject: [PATCH] When a man(7) document contains unreasonably large numbers for indentations or paragraph distances, large output may be generated, which is practically the same as an endless loop; found by jsg@ with afl. Reject such unreasonably large numbers beyond arbitrary limits similar to those used by groff (max. 65 blank lines between paragraphs and max. SHRT_MAX characters per output line) and fall back to defaults when exceeded. Having the limits behave in exactly the same way is not relevant. --- usr.bin/mandoc/man_term.c | 29 +++++++++++++++++++---------- usr.bin/mandoc/term.c | 6 ++++-- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/usr.bin/mandoc/man_term.c b/usr.bin/mandoc/man_term.c index 68324f294c3..314f8fd7325 100644 --- a/usr.bin/mandoc/man_term.c +++ b/usr.bin/mandoc/man_term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: man_term.c,v 1.116 2014/12/23 13:48:15 schwarze Exp $ */ +/* $OpenBSD: man_term.c,v 1.117 2014/12/24 09:57:41 schwarze Exp $ */ /* * Copyright (c) 2008-2012 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -430,6 +431,8 @@ pre_in(DECL_ARGS) p->offset += v; else p->offset = v; + if (p->offset > SHRT_MAX) + p->offset = term_len(p, p->defindent); return(0); } @@ -506,16 +509,16 @@ pre_HP(DECL_ARGS) if ((nn = n->parent->head->child) != NULL && a2roffsu(nn->string, &su, SCALE_EN)) { len = term_hspan(p, &su); + if (len < 0 && (size_t)(-len) > mt->offset) + len = -mt->offset; + else if (len > SHRT_MAX) + len = term_len(p, p->defindent); mt->lmargin[mt->lmargincur] = len; } else len = mt->lmargin[mt->lmargincur]; p->offset = mt->offset; - if (len > 0 || (size_t)(-len) < mt->offset) - p->rmargin = mt->offset + len; - else - p->rmargin = 0; - + p->rmargin = mt->offset + len; return(1); } @@ -580,9 +583,11 @@ pre_IP(DECL_ARGS) (nn = nn->next) != NULL && a2roffsu(nn->string, &su, SCALE_EN)) { len = term_hspan(p, &su); - mt->lmargin[mt->lmargincur] = len; if (len < 0 && (size_t)(-len) > mt->offset) len = -mt->offset; + else if (len > SHRT_MAX) + len = term_len(p, p->defindent); + mt->lmargin[mt->lmargincur] = len; } else len = mt->lmargin[mt->lmargincur]; @@ -660,9 +665,11 @@ pre_TP(DECL_ARGS) nn->string != NULL && ! (MAN_LINE & nn->flags) && a2roffsu(nn->string, &su, SCALE_EN)) { len = term_hspan(p, &su); - mt->lmargin[mt->lmargincur] = len; if (len < 0 && (size_t)(-len) > mt->offset) len = -mt->offset; + else if (len > SHRT_MAX) + len = term_len(p, p->defindent); + mt->lmargin[mt->lmargincur] = len; } else len = mt->lmargin[mt->lmargincur]; @@ -843,10 +850,11 @@ pre_RS(DECL_ARGS) break; } + len = SHRT_MAX + 1; if ((n = n->parent->head->child) != NULL && a2roffsu(n->string, &su, SCALE_EN)) len = term_hspan(p, &su); - else + if (len > SHRT_MAX) len = term_len(p, p->defindent); if (len > 0 || (size_t)(-len) < mt->offset) @@ -879,10 +887,11 @@ post_RS(DECL_ARGS) break; } + len = SHRT_MAX + 1; if ((n = n->parent->head->child) != NULL && a2roffsu(n->string, &su, SCALE_EN)) len = term_hspan(p, &su); - else + if (len > SHRT_MAX) len = term_len(p, p->defindent); if (len < 0 || (size_t)len < mt->offset) diff --git a/usr.bin/mandoc/term.c b/usr.bin/mandoc/term.c index 21443c7111e..76836aac3ef 100644 --- a/usr.bin/mandoc/term.c +++ b/usr.bin/mandoc/term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: term.c,v 1.100 2014/12/23 13:48:15 schwarze Exp $ */ +/* $OpenBSD: term.c,v 1.101 2014/12/24 09:57:41 schwarze Exp $ */ /* * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons * Copyright (c) 2010-2014 Ingo Schwarze @@ -771,6 +771,7 @@ int term_vspan(const struct termp *p, const struct roffsu *su) { double r; + int ri; switch (su->unit) { case SCALE_BU: @@ -806,7 +807,8 @@ term_vspan(const struct termp *p, const struct roffsu *su) abort(); /* NOTREACHED */ } - return(r > 0.0 ? r + 0.4995 : r - 0.4995); + ri = r > 0.0 ? r + 0.4995 : r - 0.4995; + return(ri < 66 ? ri : 1); } int -- 2.20.1