[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Wed Dec 16 11:37:34 UTC 2015


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 <metze at 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 <slow at 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 <slow at samba.org>
    Reviewed-by: Stefan Metzmacher <metze at samba.org>

commit f36cb71c330a52106e36028b3029d952257baf15
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Pair-programmed-with: Andrew Bartlett <abartlet at samba.org>
    Pair-programmed-with: Garming Sam <garming at catalyst.net.nz>
    Pair-programmed-with: Stefan Metzmacher <metze at samba.org>
    Pair-programmed-with: Ralph Boehme <slow at samba.org>

commit 538d305de91e34a2938f5f219f18bf0e1918763f
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Pair-programmed-with: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit a118d4220ed85749c07fb43c1229d9e2fecbea6b
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Pair-programmed-with: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit ba5dbda6d0174a59d221c45cca52ecd232820d48
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>

commit 0454b95657846fcecf0f51b6f1194faac02518bd
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Pair-programmed-with: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit 7f51ec8c4ed9ba1f53d722e44fb6fb3cde933b72
Author: Douglas Bagnall <douglas.bagnall at 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.bagnall at catalyst.net.nz>
    Pair-programmed-with: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit aa6c27148b9d3f8c1e4fdd5dd46bfecbbd0ca465
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at samba.org>

commit ec504dbf69636a554add1f3d5703dd6c3ad450b8
Author: Jeremy Allison <jra at 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 <jra at samba.org>
    Reviewed-by: Ralph Boehme <slow at 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



More information about the samba-cvs mailing list