summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Schwarze <schwarze@openbsd.org>2017-02-10 16:20:34 +0000
committerIngo Schwarze <schwarze@openbsd.org>2017-02-10 16:20:34 +0000
commita68d897a41b530bdc20192b48d23b5c52edf457c (patch)
tree63e747725c89b05fd3af30871c0f16fb9bbc1587
parent33be0794e265a46ae95f2b46b2d4e7d6f60e3f66 (diff)
downloadmandoc-a68d897a41b530bdc20192b48d23b5c52edf457c.tar.gz
In the SYNOPSIS, .Nm blocks can get broken if one of their children
gets broken. In that case, mark them as BROKEN and ENDED and make sure they get closed out together with the child. Fixes tree corruption leeding to a NULL dereference found by tb@ with afl(1) in: .Sh SYNOPSIS .Bl .Oo .Nm .Bk .Oc .It (where .Bk is the child and .Oo is the breaker). A simpler form of the same corruption (without crash) is visible in: .Sh SYNOPSIS .Ao .Nm .Bo .Ac .Bc text where the text ended up inside the .Nm (child .Bo, breaker .Ao).
-rw-r--r--NEWS2
-rw-r--r--mdoc_macro.c20
2 files changed, 16 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 25ba44fa..28d5bffc 100644
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,8 @@ Changes in version 1.14.1, released on February XXX, 2017
for macro sequences like .Bl .Bl .It Bo .El .It.
* mdoc(7): Fix syntax tree corruption leading to NULL dereference
caused by .Ta following a nested .Bl -column breaking another block.
+ * mdoc(7): Fix syntax tree corruption sometimes leading to NULL
+ dereference caused by indirectly broken .Nm blocks in the SYNOPSIS.
* mdoc(7) -Thtml: Fix a NULL dereference for .Bl -column with 0 columns.
* mdoc(7): Fix NULL dereference if the only child of the head
of the first .Sh was an empty in-line macro.
diff --git a/mdoc_macro.c b/mdoc_macro.c
index facec52e..30323293 100644
--- a/mdoc_macro.c
+++ b/mdoc_macro.c
@@ -575,16 +575,24 @@ blk_exp_close(MACRO_PROT_ARGS)
}
/*
- * Mismatching end macros can never break anything,
- * SYNOPSIS name blocks can never be broken,
+ * Mismatching end macros can never break anything
* and we only care about the breaking of BLOCKs.
*/
- if (body == NULL ||
- n->tok == MDOC_Nm ||
- n->type != ROFFT_BLOCK)
+ if (body == NULL || n->type != ROFFT_BLOCK)
continue;
+ /*
+ * SYNOPSIS name blocks can not be broken themselves,
+ * but they do get broken together with a broken child.
+ */
+
+ if (n->tok == MDOC_Nm) {
+ if (later != NULL)
+ n->flags |= NODE_BROKEN | NODE_ENDED;
+ continue;
+ }
+
if (n->tok == MDOC_It) {
itblk = n;
continue;
@@ -987,7 +995,7 @@ blk_full(MACRO_PROT_ARGS)
/* Close out prior implicit scopes. */
- rew_last(mdoc, n);
+ rew_pending(mdoc, n);
}
/* Skip items outside lists. */