Description: fix information leak via incorrect string length handling Origin: upstream, https://bugzilla.samba.org/show_bug.cgi?id=11599 Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599 Bug: https://bugzilla.samba.org/show_bug.cgi?id=11636 Index: samba-3.6.3/lib/util/charset/charset.h =================================================================== --- samba-3.6.3.orig/lib/util/charset/charset.h 2012-01-29 14:40:43.000000000 -0500 +++ samba-3.6.3/lib/util/charset/charset.h 2016-01-04 14:50:34.009160242 -0500 @@ -175,15 +175,16 @@ charset_t from, charset_t to); const char *charset_name(struct smb_iconv_convenience *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_convenience_ext(struct smb_iconv_convenience *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_convenience(struct smb_iconv_convenience *ic, const char *str, size_t *size); ssize_t push_codepoint_convenience(struct smb_iconv_convenience *ic, Index: samba-3.6.3/lib/util/charset/codepoints.c =================================================================== --- samba-3.6.3.orig/lib/util/charset/codepoints.c 2012-01-29 14:40:43.000000000 -0500 +++ samba-3.6.3/lib/util/charset/codepoints.c 2016-01-04 14:50:34.013160289 -0500 @@ -346,7 +346,8 @@ */ _PUBLIC_ codepoint_t next_codepoint_convenience_ext( struct smb_iconv_convenience *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 */ @@ -357,7 +358,10 @@ size_t olen; char *outbuf; - if ((str[0] & 0x80) == 0) { + + if (((str[0] & 0x80) == 0) && (src_charset == CH_DOS || + src_charset == CH_UNIX || + src_charset == CH_UTF8)) { *bytes_consumed = 1; return (codepoint_t)str[0]; } @@ -366,7 +370,7 @@ * 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); @@ -424,7 +428,13 @@ _PUBLIC_ codepoint_t next_codepoint_convenience(struct smb_iconv_convenience *ic, const char *str, size_t *size) { - return next_codepoint_convenience_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_convenience_ext(ic, str, strnlen(str, 5), CH_UNIX, size); } /* @@ -486,10 +496,10 @@ 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_convenience_ext(get_iconv_convenience(), str, + return next_codepoint_convenience_ext(get_iconv_convenience(), str, len, src_charset, size); } Index: samba-3.6.3/lib/util/charset/util_unistr.c =================================================================== --- samba-3.6.3.orig/lib/util/charset/util_unistr.c 2012-01-29 14:40:43.000000000 -0500 +++ samba-3.6.3/lib/util/charset/util_unistr.c 2016-01-04 14:50:34.017160336 -0500 @@ -218,7 +218,11 @@ while (*s) { size_t c_size; - codepoint_t c = next_codepoint_convenience_ext(ic, s, src_charset, &c_size); + codepoint_t c = next_codepoint_convenience_ext(ic, + s, + strnlen(s, 5), + src_charset, + &c_size); s += c_size; switch (dst_charset) { @@ -483,10 +487,15 @@ return NULL; } - while (n-- && *src) { + while (n && *src) { size_t c_size; - codepoint_t c = next_codepoint_convenience(iconv_convenience, src, &c_size); + codepoint_t c = next_codepoint_convenience_ext(iconv_convenience, + src, + n, + CH_UNIX, + &c_size); src += c_size; + n -= c_size; c = toupper_m(c); Index: samba-3.6.3/source3/lib/util_str.c =================================================================== --- samba-3.6.3.orig/source3/lib/util_str.c 2012-01-29 14:40:43.000000000 -0500 +++ samba-3.6.3/source3/lib/util_str.c 2016-01-04 14:50:34.013160289 -0500 @@ -1486,7 +1486,7 @@ while (*s) { size_t c_size; - codepoint_t c = next_codepoint_ext(s, src_charset, &c_size); + codepoint_t c = next_codepoint_ext(s, strnlen(s, 5), src_charset, &c_size); s += c_size; switch (dst_charset) {