diff options
author | 2017-02-17 03:01:39 +0000 | |
---|---|---|
committer | 2017-02-17 03:01:39 +0000 | |
commit | 972cfc25c1461f9d25ba8e7b0cbda52a9ad62ccb (patch) | |
tree | 2497c1f16ab670e67b7e68fd0635b86596892d6f | |
parent | Do not show rsa1 key type in usage when compiled without SSH1 support. (diff) | |
download | wireguard-openbsd-972cfc25c1461f9d25ba8e7b0cbda52a9ad62ccb.tar.xz wireguard-openbsd-972cfc25c1461f9d25ba8e7b0cbda52a9ad62ccb.zip |
Fix a read buffer overrun that copied random data from memory into
text nodes when a string passed to deroff() ended in a backslash
and the byte after the terminating NUL was non-NUL, found by tb@
with afl(1).
Invalid bytes so copied with the high bit set could later sometimes
trigger another out of bounds read access to static memory in
roff_strdup(), so add an assertion there to abort safely in case
of similar data corruption.
-rw-r--r-- | usr.bin/mandoc/roff.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/usr.bin/mandoc/roff.c b/usr.bin/mandoc/roff.c index 3bb4fe4c45d..1ba0ed3c510 100644 --- a/usr.bin/mandoc/roff.c +++ b/usr.bin/mandoc/roff.c @@ -1,4 +1,4 @@ -/* $OpenBSD: roff.c,v 1.160 2017/01/12 18:02:24 schwarze Exp $ */ +/* $OpenBSD: roff.c,v 1.161 2017/02/17 03:01:39 schwarze Exp $ */ /* * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv> * Copyright (c) 2010-2015, 2017 Ingo Schwarze <schwarze@openbsd.org> @@ -1224,15 +1224,22 @@ deroff(char **dest, const struct roff_node *n) /* Skip leading whitespace. */ for (cp = n->string; *cp != '\0'; cp++) { - if (cp[0] == '\\' && strchr(" %&0^|~", cp[1]) != NULL) + if (cp[0] == '\\' && cp[1] != '\0' && + strchr(" %&0^|~", cp[1]) != NULL) cp++; else if ( ! isspace((unsigned char)*cp)) break; } + /* Skip trailing backslash. */ + + sz = strlen(cp); + if (cp[sz - 1] == '\\') + sz--; + /* Skip trailing whitespace. */ - for (sz = strlen(cp); sz; sz--) + for (; sz; sz--) if ( ! isspace((unsigned char)cp[sz-1])) break; @@ -3356,7 +3363,8 @@ roff_strdup(const struct roff *r, const char *p) ssz = 0; while ('\0' != *p) { - if ('\\' != *p && r->xtab && r->xtab[(int)*p].p) { + assert((unsigned int)*p < 128); + if ('\\' != *p && r->xtab && r->xtab[(unsigned int)*p].p) { sz = r->xtab[(int)*p].sz; res = mandoc_realloc(res, ssz + sz + 1); memcpy(res + ssz, r->xtab[(int)*p].p, sz); |