[SCM] Samba Shared Repository - branch v4-14-stable updated

Karolin Seeger kseeger at samba.org
Thu Apr 29 08:09:35 UTC 2021


The branch, v4-14-stable has been updated
       via  e29fc62e1d6 VERSION: Disable GIT_SNAPSHOT for the 4.14.4 release.
       via  45f106c1218 WHATSNEW: Add release notes for Samba 4.14.4.
       via  55b8f31679b CVE-2021-20254 passdb: Simplify sids_to_unixids()
       via  77aa340ad8c VERSION: Bump version up to 4.14.4...
      from  def81d0a59d VERSION: Disable GIT_SNAPSHOT for the 4.14.3 release.

https://git.samba.org/?p=samba.git;a=shortlog;h=v4-14-stable


- Log -----------------------------------------------------------------
commit e29fc62e1d60a1add177fca059d0d67dcf6a1866
Author: Karolin Seeger <kseeger at samba.org>
Date:   Mon Apr 26 10:26:38 2021 +0200

    VERSION: Disable GIT_SNAPSHOT for the 4.14.4 release.
    
    BUG 14571: CVE-2021-20254: Buffer overrun in sids_to_unixids().
    
    Signed-off-by: Karolin Seeger <kseeger at samba.org>

commit 45f106c121814c0166fe7f9905b55c05a67dbda0
Author: Karolin Seeger <kseeger at samba.org>
Date:   Mon Apr 26 10:26:10 2021 +0200

    WHATSNEW: Add release notes for Samba 4.14.4.
    
    Signed-off-by: Karolin Seeger <kseeger at samba.org>

commit 55b8f31679b57545d7808cae8527663d770b10bc
Author: Volker Lendecke <vl at samba.org>
Date:   Sat Feb 20 15:50:12 2021 +0100

    CVE-2021-20254 passdb: Simplify sids_to_unixids()
    
    Best reviewed with "git show -b", there's a "continue" statement that
    changes subsequent indentation.
    
    Decouple lookup status of ids from ID_TYPE_NOT_SPECIFIED
    
    Add comments to explain the use of the three lookup
    loops.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14571
    
    Signed-off-by: Volker Lendecke <vl at samba.org>
    Reviewed-by: Jeremy Allison <jra at samba.org>
    
    (cherry-picked from commit for master)

commit 77aa340ad8c22a1f3ea43c90fbcedf5a424de56b
Author: Karolin Seeger <kseeger at samba.org>
Date:   Mon Apr 19 09:57:25 2021 +0200

    VERSION: Bump version up to 4.14.4...
    
    and re-enable GIT_SNAPSHOT.
    
    Signed-off-by: Karolin Seeger <kseeger at samba.org>
    (cherry picked from commit a8b9ea7e1aa4f526bd73baee45f0a3483c95381a)

-----------------------------------------------------------------------

Summary of changes:
 VERSION                     |   2 +-
 WHATSNEW.txt                |  68 +++++++++++++++++++++++-
 source3/passdb/lookup_sid.c | 123 ++++++++++++++++++++++++++++++++++++--------
 3 files changed, 168 insertions(+), 25 deletions(-)


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index fbdb45a2349..4b9426fa79b 100644
--- a/VERSION
+++ b/VERSION
@@ -25,7 +25,7 @@
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=14
-SAMBA_VERSION_RELEASE=3
+SAMBA_VERSION_RELEASE=4
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 71eff9a756c..8fa0ee3caf1 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,68 @@
+                   ==============================
+                   Release Notes for Samba 4.14.4
+                           April 29, 2021
+                   ==============================
+
+
+This is a security release in order to address the following defect:
+
+o CVE-2021-20254: Negative idmap cache entries can cause incorrect group entries
+  in the Samba file server process token.
+
+
+=======
+Details
+=======
+
+o  CVE-2021-20254:
+   The Samba smbd file server must map Windows group identities (SIDs) into unix
+   group ids (gids). The code that performs this had a flaw that could allow it
+   to read data beyond the end of the array in the case where a negative cache
+   entry had been added to the mapping cache. This could cause the calling code
+   to return those values into the process token that stores the group
+   membership for a user.
+
+   Most commonly this flaw caused the calling code to crash, but an alert user
+   (Peter Eriksson, IT Department, Linköping University) found this flaw by
+   noticing an unprivileged user was able to delete a file within a network
+   share that they should have been disallowed access to.
+
+   Analysis of the code paths has not allowed us to discover a way for a
+   remote user to be able to trigger this flaw reproducibly or on demand,
+   but this CVE has been issued out of an abundance of caution.
+
+
+Changes since 4.14.3
+--------------------
+
+o  Volker Lendecke <vl at samba.org>
+   * BUG 14571: CVE-2021-20254: Fix buffer overrun in sids_to_unixids().
+
+
+#######################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical IRC channel on irc.freenode.net.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored.  All bug reports should
+be filed under the Samba 4.1 and newer product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
+
+
                    ==============================
                    Release Notes for Samba 4.14.3
                            April 20, 2021
@@ -67,8 +132,7 @@ database (https://bugzilla.samba.org/).
 ======================================================================
 
 
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
 
 
                    ==============================
diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
index cf80a300189..0e01467b3cb 100644
--- a/source3/passdb/lookup_sid.c
+++ b/source3/passdb/lookup_sid.c
@@ -29,6 +29,7 @@
 #include "../libcli/security/security.h"
 #include "lib/winbind_util.h"
 #include "../librpc/gen_ndr/idmap.h"
+#include "lib/util/bitmap.h"
 
 static bool lookup_unix_user_name(const char *name, struct dom_sid *sid)
 {
@@ -1266,7 +1267,9 @@ bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
 {
 	struct wbcDomainSid *wbc_sids = NULL;
 	struct wbcUnixId *wbc_ids = NULL;
+	struct bitmap *found = NULL;
 	uint32_t i, num_not_cached;
+	uint32_t wbc_ids_size = 0;
 	wbcErr err;
 	bool ret = false;
 
@@ -1274,6 +1277,20 @@ bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
 	if (wbc_sids == NULL) {
 		return false;
 	}
+	found = bitmap_talloc(wbc_sids, num_sids);
+	if (found == NULL) {
+		goto fail;
+	}
+
+	/*
+	 * We go through the requested SID array three times.
+	 * First time to look for global_sid_Unix_Users
+	 * and global_sid_Unix_Groups SIDS, and to look
+	 * for mappings cached in the idmap_cache.
+	 *
+	 * Use bitmap_set() to mark an ids[] array entry as
+	 * being mapped.
+	 */
 
 	num_not_cached = 0;
 
@@ -1285,17 +1302,20 @@ bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
 				       &sids[i], &rid)) {
 			ids[i].type = ID_TYPE_UID;
 			ids[i].id = rid;
+			bitmap_set(found, i);
 			continue;
 		}
 		if (sid_peek_check_rid(&global_sid_Unix_Groups,
 				       &sids[i], &rid)) {
 			ids[i].type = ID_TYPE_GID;
 			ids[i].id = rid;
+			bitmap_set(found, i);
 			continue;
 		}
 		if (idmap_cache_find_sid2unixid(&sids[i], &ids[i], &expired)
 		    && !expired)
 		{
+			bitmap_set(found, i);
 			continue;
 		}
 		ids[i].type = ID_TYPE_NOT_SPECIFIED;
@@ -1306,62 +1326,121 @@ bool sids_to_unixids(const struct dom_sid *sids, uint32_t num_sids,
 	if (num_not_cached == 0) {
 		goto done;
 	}
-	wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, num_not_cached);
+
+	/*
+	 * For the ones that we couldn't map in the loop above, query winbindd
+	 * via wbcSidsToUnixIds().
+	 */
+
+	wbc_ids_size = num_not_cached;
+	wbc_ids = talloc_array(talloc_tos(), struct wbcUnixId, wbc_ids_size);
 	if (wbc_ids == NULL) {
 		goto fail;
 	}
-	for (i=0; i<num_not_cached; i++) {
+	for (i=0; i<wbc_ids_size; i++) {
 		wbc_ids[i].type = WBC_ID_TYPE_NOT_SPECIFIED;
+		wbc_ids[i].id.gid = (uint32_t)-1;
 	}
-	err = wbcSidsToUnixIds(wbc_sids, num_not_cached, wbc_ids);
+	err = wbcSidsToUnixIds(wbc_sids, wbc_ids_size, wbc_ids);
 	if (!WBC_ERROR_IS_OK(err)) {
 		DEBUG(10, ("wbcSidsToUnixIds returned %s\n",
 			   wbcErrorString(err)));
 	}
 
+	/*
+	 * Second time through the SID array, replace
+	 * the ids[] entries that wbcSidsToUnixIds() was able to
+	 * map.
+	 *
+	 * Use bitmap_set() to mark an ids[] array entry as
+	 * being mapped.
+	 */
+
 	num_not_cached = 0;
 
 	for (i=0; i<num_sids; i++) {
-		if (ids[i].type == ID_TYPE_NOT_SPECIFIED) {
-			switch (wbc_ids[num_not_cached].type) {
-			case WBC_ID_TYPE_UID:
-				ids[i].type = ID_TYPE_UID;
-				ids[i].id = wbc_ids[num_not_cached].id.uid;
-				break;
-			case WBC_ID_TYPE_GID:
-				ids[i].type = ID_TYPE_GID;
-				ids[i].id = wbc_ids[num_not_cached].id.gid;
-				break;
-			default:
-				/* The types match, and wbcUnixId -> id is a union anyway */
-				ids[i].type = (enum id_type)wbc_ids[num_not_cached].type;
-				ids[i].id = wbc_ids[num_not_cached].id.gid;
-				break;
-			}
-			num_not_cached += 1;
+		if (bitmap_query(found, i)) {
+			continue;
+		}
+
+		SMB_ASSERT(num_not_cached < wbc_ids_size);
+
+		switch (wbc_ids[num_not_cached].type) {
+		case WBC_ID_TYPE_UID:
+			ids[i].type = ID_TYPE_UID;
+			ids[i].id = wbc_ids[num_not_cached].id.uid;
+			bitmap_set(found, i);
+			break;
+		case WBC_ID_TYPE_GID:
+			ids[i].type = ID_TYPE_GID;
+			ids[i].id = wbc_ids[num_not_cached].id.gid;
+			bitmap_set(found, i);
+			break;
+		case WBC_ID_TYPE_BOTH:
+			ids[i].type = ID_TYPE_BOTH;
+			ids[i].id = wbc_ids[num_not_cached].id.uid;
+			bitmap_set(found, i);
+			break;
+		case WBC_ID_TYPE_NOT_SPECIFIED:
+			/*
+			 * wbcSidsToUnixIds() wasn't able to map this
+			 * so we still need to check legacy_sid_to_XXX()
+			 * below. Don't mark the bitmap entry
+			 * as being found so the final loop knows
+			 * to try and map this entry.
+			 */
+			ids[i].type = ID_TYPE_NOT_SPECIFIED;
+			ids[i].id = (uint32_t)-1;
+			break;
+		default:
+			/*
+			 * A successful return from wbcSidsToUnixIds()
+			 * cannot return anything other than the values
+			 * checked for above. Ensure this is so.
+			 */
+			smb_panic(__location__);
+			break;
 		}
+		num_not_cached += 1;
 	}
 
+	/*
+	 * Third and final time through the SID array,
+	 * try legacy_sid_to_gid()/legacy_sid_to_uid()
+	 * for entries we haven't already been able to
+	 * map.
+	 *
+	 * Use bitmap_set() to mark an ids[] array entry as
+	 * being mapped.
+	 */
+
 	for (i=0; i<num_sids; i++) {
-		if (ids[i].type != ID_TYPE_NOT_SPECIFIED) {
+		if (bitmap_query(found, i)) {
 			continue;
 		}
 		if (legacy_sid_to_gid(&sids[i], &ids[i].id)) {
 			ids[i].type = ID_TYPE_GID;
+			bitmap_set(found, i);
 			continue;
 		}
 		if (legacy_sid_to_uid(&sids[i], &ids[i].id)) {
 			ids[i].type = ID_TYPE_UID;
+			bitmap_set(found, i);
 			continue;
 		}
 	}
 done:
+	/*
+	 * Pass through the return array for consistency.
+	 * Any ids[].id mapped to (uint32_t)-1 must be returned
+	 * as ID_TYPE_NOT_SPECIFIED.
+	 */
 	for (i=0; i<num_sids; i++) {
 		switch(ids[i].type) {
 		case ID_TYPE_GID:
 		case ID_TYPE_UID:
 		case ID_TYPE_BOTH:
-			if (ids[i].id == -1) {
+			if (ids[i].id == (uint32_t)-1) {
 				ids[i].type = ID_TYPE_NOT_SPECIFIED;
 			}
 			break;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list