The branch, master has been updated via 067640b Merge tag 'ldb-1.1.24' into master via b63e3b9 ldb: version 1.1.24 via f36cb71 CVE-2015-5330: ldb_dn_explode: copy strings by length, not terminators via 538d305 CVE-2015-5330: next_codepoint_handle_ext: don't short-circuit UTF16 low bytes via a118d42 CVE-2015-5330: strupper_talloc_n_handle(): properly count characters via ba5dbda CVE-2015-5330: Fix handling of unicode near string endings via 0454b95 CVE-2015-5330: ldb_dn_escape_value: use known string length, not strlen() via 7f51ec8 CVE-2015-5330: ldb_dn: simplify and fix ldb_dn_escape_internal() via aa6c271 CVE-2015-3223: lib: ldb: Use memmem binary search, not strstr text search. via ec504db CVE-2015-3223: lib: ldb: Cope with canonicalise_fn returning string "", length 0. from 2058ce2 smbd: make "hide dot files" option work with "store dos attributes = yes"
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 067640b04a6a95927b6aea40bf2a48a3637aff8d Merge: 2058ce2 b63e3b9 Author: Stefan Metzmacher <me...@samba.org> Date: Wed Dec 16 12:31:33 2015 +0100 Merge tag 'ldb-1.1.24' into master ldb: tag release ldb-1.1.24 commit b63e3b9f3e7d50ea128d7e4f675abe8fbadbd69e Author: Ralph Boehme <s...@samba.org> Date: Tue Dec 8 12:08:14 2015 +0100 ldb: version 1.1.24 * fix for CVE-2015-5330, bug 11599 * fix for CVE-2015-3223, bug 11325 * move ldb_(un)pack_data into ldb_module.h for testing * fix installation of _ldb_text.py * fix propagation of LDB errors through TDB * fix bug triggered by having an empty message in database during search Bug: https://bugzilla.samba.org/show_bug.cgi?id=11325 Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599 Bug: https://bugzilla.samba.org/show_bug.cgi?id=11636 Signed-off-by: Ralph Boehme <s...@samba.org> Reviewed-by: Stefan Metzmacher <me...@samba.org> commit f36cb71c330a52106e36028b3029d952257baf15 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Thu Nov 26 11:17:11 2015 +1300 CVE-2015-5330: ldb_dn_explode: copy strings by length, not terminators That is, memdup(), not strdup(). The terminators might not be there. But, we have to make sure we put the terminator on, because we tend to assume the terminator is there in other places. Use talloc_set_name_const() on the resulting chunk so talloc_report() remains unchanged. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599 Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Pair-programmed-with: Andrew Bartlett <abart...@samba.org> Pair-programmed-with: Garming Sam <garm...@catalyst.net.nz> Pair-programmed-with: Stefan Metzmacher <me...@samba.org> Pair-programmed-with: Ralph Boehme <s...@samba.org> commit 538d305de91e34a2938f5f219f18bf0e1918763f Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Tue Nov 24 13:54:09 2015 +1300 CVE-2015-5330: next_codepoint_handle_ext: don't short-circuit UTF16 low bytes UTF16 contains zero bytes when it is encoding ASCII (for example), so we can't assume the absense of the 0x80 bit means a one byte encoding. No current callers use UTF16. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599 Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Pair-programmed-with: Andrew Bartlett <abart...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit a118d4220ed85749c07fb43c1229d9e2fecbea6b Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Tue Nov 24 13:49:09 2015 +1300 CVE-2015-5330: strupper_talloc_n_handle(): properly count characters When a codepoint eats more than one byte we really want to know, especially if the string is not NUL terminated. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599 Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Pair-programmed-with: Andrew Bartlett <abart...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit ba5dbda6d0174a59d221c45cca52ecd232820d48 Author: Douglas Bagnall <douglas.bagn...@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.bagn...@catalyst.net.nz> Pair-programmed-with: Andrew Bartlett <abart...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 0454b95657846fcecf0f51b6f1194faac02518bd Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Tue Nov 24 13:09:36 2015 +1300 CVE-2015-5330: ldb_dn_escape_value: use known string length, not strlen() ldb_dn_escape_internal() reports the number of bytes it copied, so lets use that number, rather than using strlen() and hoping a zero got in the right place. Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599 Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Pair-programmed-with: Andrew Bartlett <abart...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit 7f51ec8c4ed9ba1f53d722e44fb6fb3cde933b72 Author: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Date: Tue Nov 24 13:07:23 2015 +1300 CVE-2015-5330: ldb_dn: simplify and fix ldb_dn_escape_internal() Previously we relied on NUL terminated strings and jumped back and forth between copying escaped bytes and memcpy()ing un-escaped chunks. This simple version is easier to reason about and works with unterminated strings. It may also be faster as it avoids reading the string twice (first with strcspn, then with memcpy). Bug: https://bugzilla.samba.org/show_bug.cgi?id=11599 Signed-off-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz> Pair-programmed-with: Andrew Bartlett <abart...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit aa6c27148b9d3f8c1e4fdd5dd46bfecbbd0ca465 Author: Jeremy Allison <j...@samba.org> Date: Tue Jun 9 14:00:01 2015 -0700 CVE-2015-3223: lib: ldb: Use memmem binary search, not strstr text search. Values might have embedded zeros. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11325 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> commit ec504dbf69636a554add1f3d5703dd6c3ad450b8 Author: Jeremy Allison <j...@samba.org> Date: Tue Jun 9 12:42:10 2015 -0700 CVE-2015-3223: lib: ldb: Cope with canonicalise_fn returning string "", length 0. BUG: https://bugzilla.samba.org/show_bug.cgi?id=11325 Signed-off-by: Jeremy Allison <j...@samba.org> Reviewed-by: Ralph Boehme <s...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/ldb/ABI/{ldb-1.1.22.sigs => ldb-1.1.24.sigs} | 0 ...ldb-util-1.1.10.sigs => pyldb-util-1.1.24.sigs} | 0 ...util-1.1.10.sigs => pyldb-util.py3-1.1.24.sigs} | 0 lib/ldb/common/ldb_dn.c | 67 +++++++++++----------- lib/ldb/common/ldb_match.c | 33 +++++++++-- lib/ldb/wscript | 2 +- lib/util/charset/charset.h | 9 +-- lib/util/charset/codepoints.c | 29 +++++++--- lib/util/charset/util_str.c | 3 +- lib/util/charset/util_unistr.c | 6 +- 10 files changed, 93 insertions(+), 56 deletions(-) copy lib/ldb/ABI/{ldb-1.1.22.sigs => ldb-1.1.24.sigs} (100%) copy lib/ldb/ABI/{pyldb-util-1.1.10.sigs => pyldb-util-1.1.24.sigs} (100%) copy lib/ldb/ABI/{pyldb-util-1.1.10.sigs => pyldb-util.py3-1.1.24.sigs} (100%) Changeset truncated at 500 lines: diff --git a/lib/ldb/ABI/ldb-1.1.22.sigs b/lib/ldb/ABI/ldb-1.1.24.sigs similarity index 100% copy from lib/ldb/ABI/ldb-1.1.22.sigs copy to lib/ldb/ABI/ldb-1.1.24.sigs diff --git a/lib/ldb/ABI/pyldb-util-1.1.10.sigs b/lib/ldb/ABI/pyldb-util-1.1.24.sigs similarity index 100% copy from lib/ldb/ABI/pyldb-util-1.1.10.sigs copy to lib/ldb/ABI/pyldb-util-1.1.24.sigs diff --git a/lib/ldb/ABI/pyldb-util-1.1.10.sigs b/lib/ldb/ABI/pyldb-util.py3-1.1.24.sigs similarity index 100% copy from lib/ldb/ABI/pyldb-util-1.1.10.sigs copy to lib/ldb/ABI/pyldb-util.py3-1.1.24.sigs diff --git a/lib/ldb/common/ldb_dn.c b/lib/ldb/common/ldb_dn.c index 85f89c1b..dfd3b58 100644 --- a/lib/ldb/common/ldb_dn.c +++ b/lib/ldb/common/ldb_dn.c @@ -189,33 +189,23 @@ struct ldb_dn *ldb_dn_new_fmt(TALLOC_CTX *mem_ctx, /* see RFC2253 section 2.4 */ static int ldb_dn_escape_internal(char *dst, const char *src, int len) { - const char *p, *s; + char c; char *d; - size_t l; - - p = s = src; + int i; d = dst; - while (p - src < len) { - p += strcspn(p, ",=\n\r+<>#;\\\" "); - - if (p - src == len) /* found no escapable chars */ - break; - - /* copy the part of the string before the stop */ - memcpy(d, s, p - s); - d += (p - s); /* move to current position */ - - switch (*p) { + for (i = 0; i < len; i++){ + c = src[i]; + switch (c) { case ' ': - if (p == src || (p-src)==(len-1)) { + if (i == 0 || i == len - 1) { /* if at the beginning or end * of the string then escape */ *d++ = '\\'; - *d++ = *p++; + *d++ = c; } else { /* otherwise don't escape */ - *d++ = *p++; + *d++ = c; } break; @@ -231,36 +221,36 @@ static int ldb_dn_escape_internal(char *dst, const char *src, int len) case '?': /* these must be escaped using \c form */ *d++ = '\\'; - *d++ = *p++; + *d++ = c; break; - default: { + case ';': + case '\r': + case '\n': + case '=': + case '\0': { /* any others get \XX form */ unsigned char v; const char *hexbytes = "0123456789ABCDEF"; - v = *(const unsigned char *)p; + v = (const unsigned char)c; *d++ = '\\'; *d++ = hexbytes[v>>4]; *d++ = hexbytes[v&0xF]; - p++; break; } + default: + *d++ = c; } - s = p; /* move forward */ } - /* copy the last part (with zero) and return */ - l = len - (s - src); - memcpy(d, s, l + 1); - /* return the length of the resulting string */ - return (l + (d - dst)); + return (d - dst); } char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value) { char *dst; - + size_t len; if (!value.length) return NULL; @@ -271,10 +261,14 @@ char *ldb_dn_escape_value(TALLOC_CTX *mem_ctx, struct ldb_val value) return NULL; } - ldb_dn_escape_internal(dst, (const char *)value.data, value.length); - - dst = talloc_realloc(mem_ctx, dst, char, strlen(dst) + 1); + len = ldb_dn_escape_internal(dst, (const char *)value.data, value.length); + dst = talloc_realloc(mem_ctx, dst, char, len + 1); + if ( ! dst) { + talloc_free(dst); + return NULL; + } + dst[len] = '\0'; return dst; } @@ -592,12 +586,15 @@ static bool ldb_dn_explode(struct ldb_dn *dn) p++; *d++ = '\0'; - dn->components[dn->comp_num].value.data = (uint8_t *)talloc_strdup(dn->components, dt); + dn->components[dn->comp_num].value.data = \ + (uint8_t *)talloc_memdup(dn->components, dt, l + 1); dn->components[dn->comp_num].value.length = l; if ( ! dn->components[dn->comp_num].value.data) { /* ouch ! */ goto failed; } + talloc_set_name_const(dn->components[dn->comp_num].value.data, + (const char *)dn->components[dn->comp_num].value.data); dt = d; @@ -713,11 +710,13 @@ static bool ldb_dn_explode(struct ldb_dn *dn) *d++ = '\0'; dn->components[dn->comp_num].value.length = l; dn->components[dn->comp_num].value.data = - (uint8_t *)talloc_strdup(dn->components, dt); + (uint8_t *)talloc_memdup(dn->components, dt, l + 1); if ( ! dn->components[dn->comp_num].value.data) { /* ouch */ goto failed; } + talloc_set_name_const(dn->components[dn->comp_num].value.data, + (const char *)dn->components[dn->comp_num].value.data); dn->comp_num++; diff --git a/lib/ldb/common/ldb_match.c b/lib/ldb/common/ldb_match.c index a493dae..182c6ce 100644 --- a/lib/ldb/common/ldb_match.c +++ b/lib/ldb/common/ldb_match.c @@ -241,7 +241,6 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, struct ldb_val val; struct ldb_val cnk; struct ldb_val *chunk; - char *p, *g; uint8_t *save_p = NULL; unsigned int c = 0; @@ -271,6 +270,14 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, if (cnk.length > val.length) { goto mismatch; } + /* + * Empty strings are returned as length 0. Ensure + * we can cope with this. + */ + if (cnk.length == 0) { + goto mismatch; + } + if (memcmp((char *)val.data, (char *)cnk.data, cnk.length) != 0) goto mismatch; val.length -= cnk.length; val.data += cnk.length; @@ -280,20 +287,36 @@ static int ldb_wildcard_compare(struct ldb_context *ldb, } while (tree->u.substring.chunks[c]) { + uint8_t *p; chunk = tree->u.substring.chunks[c]; if(a->syntax->canonicalise_fn(ldb, ldb, chunk, &cnk) != 0) goto mismatch; - /* FIXME: case of embedded nulls */ - p = strstr((char *)val.data, (char *)cnk.data); + /* + * Empty strings are returned as length 0. Ensure + * we can cope with this. + */ + if (cnk.length == 0) { + goto mismatch; + } + /* + * Values might be binary blobs. Don't use string + * search, but memory search instead. + */ + p = memmem((const void *)val.data,val.length, + (const void *)cnk.data, cnk.length); if (p == NULL) goto mismatch; if ( (! tree->u.substring.chunks[c + 1]) && (! tree->u.substring.end_with_wildcard) ) { + uint8_t *g; do { /* greedy */ - g = strstr((char *)p + cnk.length, (char *)cnk.data); + g = memmem(p + cnk.length, + val.length - (p - val.data), + (const uint8_t *)cnk.data, + cnk.length); if (g) p = g; } while(g); } - val.length = val.length - (p - (char *)(val.data)) - cnk.length; + val.length = val.length - (p - (uint8_t *)(val.data)) - cnk.length; val.data = (uint8_t *)(p + cnk.length); c++; talloc_free(cnk.data); diff --git a/lib/ldb/wscript b/lib/ldb/wscript index 6a6cd83..2796243 100755 --- a/lib/ldb/wscript +++ b/lib/ldb/wscript @@ -1,7 +1,7 @@ #!/usr/bin/env python APPNAME = 'ldb' -VERSION = '1.1.23' +VERSION = '1.1.24' blddir = 'bin' 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..3d444a6 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 */ @@ -16668,7 +16669,10 @@ _PUBLIC_ codepoint_t next_codepoint_handle_ext( 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]; } @@ -16677,7 +16681,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 +16737,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 +16808,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 ef8a82a..550fba3 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..2cc8718 100644 --- a/lib/util/charset/util_unistr.c +++ b/lib/util/charset/util_unistr.c @@ -110,10 +110,12 @@ _PUBLIC_ char *strupper_talloc_n_handle(struct smb_iconv_handle *iconv_handle, return NULL; } - while (n-- && *src) { + 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; + n -= c_size; c = toupper_m(c); -- Samba Shared Repository