[Pkg-samba-maint] [Git][samba-team/samba][master] 4 commits: Add patch for CVE-2021-20254 (Closes: #987811)

Mathieu Parent gitlab at salsa.debian.org
Thu May 6 20:41:29 BST 2021



Mathieu Parent pushed to branch master at Debian Samba Team / samba


Commits:
07be5651 by Mathieu Parent at 2021-05-06T21:05:36+02:00
Add patch for CVE-2021-20254 (Closes: #987811)

- - - - -
2fcaf93d by Volker Lendecke at 2021-05-06T21:15:39+02:00
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

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>

(backported from patch from master)
[backport by npower at samba.org as master commit
 493f5d6b078e0b0f80d1ef25043e2834cb4fcb87 and
 58e9b62222ad62c81cdf11d704859a227cb2902b creates conflicts
 due to rename of WBC_ID_TYPE_* -> ID_TYPE_*]

- - - - -
a3e8b050 by Mathieu Parent at 2021-05-06T21:15:39+02:00
Breaks+Replaces: samba-dev (<< 2:4.11) (Closes: #987209)

- - - - -
197e2ec7 by Mathieu Parent at 2021-05-06T21:15:39+02:00
Release 2:4.13.5+dfsg-2

- - - - -


5 changed files:

- debian/changelog
- debian/control
- + debian/patches/CVE-2021-20254.patch
- debian/patches/series
- source3/passdb/lookup_sid.c


Changes:

=====================================
debian/changelog
=====================================
@@ -1,3 +1,11 @@
+samba (2:4.13.5+dfsg-2) unstable; urgency=high
+
+  * CVE-2021-20254: Negative idmap cache entries can cause incorrect group
+    entries in the Samba file server process token (Closes: #987811)
+  * Add Breaks+Replaces: samba-dev (<< 2:4.11) (Closes: #987209)
+
+ -- Mathieu Parent <sathieu at debian.org>  Thu, 06 May 2021 21:09:29 +0200
+
 samba (2:4.13.5+dfsg-1) unstable; urgency=medium
 
   * New upstream version (Closes: #984863)
@@ -45,7 +53,7 @@ samba (2:4.13.2+dfsg-3) unstable; urgency=medium
 
 samba (2:4.13.2+dfsg-2) unstable; urgency=medium
 
-  * Upload to unstable 
+  * Upload to unstable
 
  -- Mathieu Parent <sathieu at debian.org>  Wed, 18 Nov 2020 20:34:51 +0100
 


=====================================
debian/control
=====================================
@@ -421,7 +421,8 @@ Architecture: any
 Multi-Arch: same
 Depends: libwbclient0 (= ${binary:Version}), ${misc:Depends}, ${shlibs:Depends}
 Pre-Depends: dpkg (>= 1.15.6~)
-Breaks: samba-libs (<< 2:4.11.0+dfsg-1~)
+Breaks: samba-libs (<< 2:4.11.0+dfsg-1~), samba-dev (<< 2:4.11)
+Replaces: samba-dev (<< 2:4.11)
 Description: Samba winbind client library - development files
  Samba is an implementation of the SMB/CIFS protocol for Unix systems,
  providing support for cross-platform file and printer sharing with


=====================================
debian/patches/CVE-2021-20254.patch
=====================================
@@ -0,0 +1,235 @@
+From c5f31dbc3b8b86335769b9c84a0d09765cc33259 Mon Sep 17 00:00:00 2001
+From: Volker Lendecke <vl at samba.org>
+Date: Sat, 20 Feb 2021 15:50:12 +0100
+Subject: [PATCH] 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
+
+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>
+
+(backported from patch from master)
+[backport by npower at samba.org as master commit
+ 493f5d6b078e0b0f80d1ef25043e2834cb4fcb87 and
+ 58e9b62222ad62c81cdf11d704859a227cb2902b creates conflicts
+ due to rename of WBC_ID_TYPE_* -> ID_TYPE_*]
+---
+ source3/passdb/lookup_sid.c | 123 +++++++++++++++++++++++++++++-------
+ 1 file changed, 101 insertions(+), 22 deletions(-)
+
+diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c
+index 82c47b3145b..4b3aa7e435d 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)
+ {
+@@ -1247,7 +1248,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;
+ 
+@@ -1255,6 +1258,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;
+ 
+@@ -1266,17 +1283,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;
+@@ -1287,62 +1307,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 WBC_ID_TYPE_GID:
+ 		case WBC_ID_TYPE_UID:
+ 		case WBC_ID_TYPE_BOTH:
+-			if (ids[i].id == -1) {
++			if (ids[i].id == (uint32_t)-1) {
+ 				ids[i].type = ID_TYPE_NOT_SPECIFIED;
+ 			}
+ 			break;
+-- 
+2.25.1
+


=====================================
debian/patches/series
=====================================
@@ -10,3 +10,4 @@ smbd.service-Run-update-apparmor-samba-profile-befor.patch
 fix-nfs-service-name-to-nfs-kernel-server.patch
 Rename-mdfind-to-mdsearch.patch
 ctdb-config-enable-syslog-by-default.patch
+CVE-2021-20254.patch


=====================================
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)
 {
@@ -1247,7 +1248,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;
 
@@ -1255,6 +1258,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;
 
@@ -1266,17 +1283,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;
@@ -1287,62 +1307,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 WBC_ID_TYPE_GID:
 		case WBC_ID_TYPE_UID:
 		case WBC_ID_TYPE_BOTH:
-			if (ids[i].id == -1) {
+			if (ids[i].id == (uint32_t)-1) {
 				ids[i].type = ID_TYPE_NOT_SPECIFIED;
 			}
 			break;



View it on GitLab: https://salsa.debian.org/samba-team/samba/-/compare/5c06b3ca511bfe86339414d759647bf0de9f695b...197e2ec7f6fb798171ebffc3885a5241d970b396

-- 
View it on GitLab: https://salsa.debian.org/samba-team/samba/-/compare/5c06b3ca511bfe86339414d759647bf0de9f695b...197e2ec7f6fb798171ebffc3885a5241d970b396
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-samba-maint/attachments/20210506/fcc468a8/attachment-0001.htm>


More information about the Pkg-samba-maint mailing list