about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2013-09-27 13:09:46 -0400
committerRich Felker <dalias@aerifal.cx>2013-09-27 13:09:46 -0400
commit211264e46a2f1bc382a84435e904d1548de672b0 (patch)
tree86c29e9aabbcc1b713cfc2da388fc0c928a1ce1c
parente1f1df9c743af60c0e6271fcd78b59dbfd72d8ad (diff)
downloadmusl-211264e46a2f1bc382a84435e904d1548de672b0.tar.gz
musl-211264e46a2f1bc382a84435e904d1548de672b0.tar.xz
musl-211264e46a2f1bc382a84435e904d1548de672b0.zip
fix buffer overflow in mbsrtowcs
issue reported by Michael Forney:

"If wn becomes 0 after processing a chunk of 4, mbsrtowcs currently
continues on, wrapping wn around to -1, causing the rest of the string
to be processed.

This resulted in buffer overruns if there was only space in ws for wn
wide characters."

the original patch submitted added an additional check for !wn after
the loop; to avoid extra branching, I instead just changed the wn>=4
check to wn>=5 to ensure that at least one slot remains after the
word-at-a-time loop runs. this should not slow down the tail
processing on real-world usage, since an extra slot that can't be
processed in the word-at-a-time loop is needed for the null
termination anyway.
-rw-r--r--src/multibyte/mbsrtowcs.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/multibyte/mbsrtowcs.c b/src/multibyte/mbsrtowcs.c
index b9bbc33d..066cce60 100644
--- a/src/multibyte/mbsrtowcs.c
+++ b/src/multibyte/mbsrtowcs.c
@@ -59,7 +59,7 @@ resume0:
 			return wn0;
 		}
 		if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
-			while (wn>=4 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
+			while (wn>=5 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
 				*ws++ = *s++;
 				*ws++ = *s++;
 				*ws++ = *s++;