[Pkg-samba-maint] [samba] 06/19: CVE-2015-5330: Fix handling of unicode near string endings

Jelmer Vernooij jelmer at moszumanska.debian.org
Fri Dec 18 13:08:28 UTC 2015


This is an automated email from the git hooks/post-receive script.

jelmer pushed a commit to branch upstream_4.3
in repository samba.

commit fc9e5048bf2bb2f5f0f538735dbc5661f2b4ab0f
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date:   Tue Nov 24 13:47:16 2015 +1300

    CVE-2015-5330: Fix handling of unicode near string endings
    
    Until now next_codepoint_ext() and next_codepoint_handle_ext() were
    using strnlen(str, 5) to determine how much string they should try to
    decode. This ended up looking past the end of the string when it was not
    null terminated and the final character looked like a multi-byte encoding.
    The fix is to let the caller say how long the string can be.
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599
    
    Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
    Pair-programmed-with: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>
---
 lib/util/charset/charset.h     |  9 +++++----
 lib/util/charset/codepoints.c  | 24 ++++++++++++++++--------
 lib/util/charset/util_str.c    |  3 ++-
 lib/util/charset/util_unistr.c |  3 ++-
 4 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h
index 0d69d31..ca7a437 100644
--- a/lib/util/charset/charset.h
+++ b/lib/util/charset/charset.h
@@ -174,15 +174,16 @@ smb_iconv_t get_conv_handle(struct smb_iconv_handle *ic,
 			    charset_t from, charset_t to);
 const char *charset_name(struct smb_iconv_handle *ic, charset_t ch);
 
-codepoint_t next_codepoint_ext(const char *str, charset_t src_charset,
-			       size_t *size);
+codepoint_t next_codepoint_ext(const char *str, size_t len,
+			       charset_t src_charset, size_t *size);
 codepoint_t next_codepoint(const char *str, size_t *size);
 ssize_t push_codepoint(char *str, codepoint_t c);
 
 /* codepoints */
 codepoint_t next_codepoint_handle_ext(struct smb_iconv_handle *ic,
-			    const char *str, charset_t src_charset,
-			    size_t *size);
+				      const char *str, size_t len,
+				      charset_t src_charset,
+				      size_t *size);
 codepoint_t next_codepoint_handle(struct smb_iconv_handle *ic,
 			    const char *str, size_t *size);
 ssize_t push_codepoint_handle(struct smb_iconv_handle *ic,
diff --git a/lib/util/charset/codepoints.c b/lib/util/charset/codepoints.c
index 19319ba..99d209f 100644
--- a/lib/util/charset/codepoints.c
+++ b/lib/util/charset/codepoints.c
@@ -16657,7 +16657,8 @@ smb_iconv_t get_conv_handle(struct smb_iconv_handle *ic,
  */
 _PUBLIC_ codepoint_t next_codepoint_handle_ext(
 			struct smb_iconv_handle *ic,
-			const char *str, charset_t src_charset,
+			const char *str, size_t len,
+			charset_t src_charset,
 			size_t *bytes_consumed)
 {
 	/* it cannot occupy more than 4 bytes in UTF16 format */
@@ -16677,7 +16678,7 @@ _PUBLIC_ codepoint_t next_codepoint_handle_ext(
 	 * we assume that no multi-byte character can take more than 5 bytes.
 	 * This is OK as we only support codepoints up to 1M (U+100000)
 	 */
-	ilen_orig = strnlen(str, 5);
+	ilen_orig = MIN(len, 5);
 	ilen = ilen_orig;
 
 	descriptor = get_conv_handle(ic, src_charset, CH_UTF16);
@@ -16733,9 +16734,16 @@ _PUBLIC_ codepoint_t next_codepoint_handle_ext(
   return INVALID_CODEPOINT if the next character cannot be converted
 */
 _PUBLIC_ codepoint_t next_codepoint_handle(struct smb_iconv_handle *ic,
-				    const char *str, size_t *size)
+					   const char *str, size_t *size)
 {
-	return next_codepoint_handle_ext(ic, str, CH_UNIX, size);
+	/*
+	 * We assume that no multi-byte character can take more than 5 bytes
+	 * thus avoiding walking all the way down a long string. This is OK as
+	 * Unicode codepoints only go up to (U+10ffff), which can always be
+	 * encoded in 4 bytes or less.
+	 */
+	return next_codepoint_handle_ext(ic, str, strnlen(str, 5), CH_UNIX,
+					 size);
 }
 
 /*
@@ -16797,11 +16805,11 @@ _PUBLIC_ ssize_t push_codepoint_handle(struct smb_iconv_handle *ic,
 	return 5 - olen;
 }
 
-_PUBLIC_ codepoint_t next_codepoint_ext(const char *str, charset_t src_charset,
-					size_t *size)
+_PUBLIC_ codepoint_t next_codepoint_ext(const char *str, size_t len,
+					charset_t src_charset, size_t *size)
 {
-	return next_codepoint_handle_ext(get_iconv_handle(), str,
-					      src_charset, size);
+	return next_codepoint_handle_ext(get_iconv_handle(), str, len,
+					 src_charset, size);
 }
 
 _PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size)
diff --git a/lib/util/charset/util_str.c b/lib/util/charset/util_str.c
index c1b81f1..90197e0 100644
--- a/lib/util/charset/util_str.c
+++ b/lib/util/charset/util_str.c
@@ -210,7 +210,8 @@ _PUBLIC_ size_t strlen_m_ext_handle(struct smb_iconv_handle *ic,
 
 	while (*s) {
 		size_t c_size;
-		codepoint_t c = next_codepoint_handle_ext(ic, s, src_charset, &c_size);
+		codepoint_t c = next_codepoint_handle_ext(ic, s, strnlen(s, 5),
+							  src_charset, &c_size);
 		s += c_size;
 
 		switch (dst_charset) {
diff --git a/lib/util/charset/util_unistr.c b/lib/util/charset/util_unistr.c
index e4ae650..f299269 100644
--- a/lib/util/charset/util_unistr.c
+++ b/lib/util/charset/util_unistr.c
@@ -112,7 +112,8 @@ _PUBLIC_ char *strupper_talloc_n_handle(struct smb_iconv_handle *iconv_handle,
 
 	while (n-- && *src) {
 		size_t c_size;
-		codepoint_t c = next_codepoint_handle(iconv_handle, src, &c_size);
+		codepoint_t c = next_codepoint_handle_ext(iconv_handle, src, n,
+							  CH_UNIX, &c_size);
 		src += c_size;
 
 		c = toupper_m(c);

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-samba/samba.git




More information about the Pkg-samba-maint mailing list