The branch, v4-12-stable has been updated
       via  703c6301013 VERSION: Disable GIT_SNAPSHOT for the 4.12.15 release.
       via  05214a24860 WHATSNEW: Add release notes for Samba 4.12.15.
       via  6a6a33274c0 CVE-2021-20254 passdb: Simplify sids_to_unixids()
       via  80c8c8552ed VERSION: Enable GIT_SNAPSHOT.
       via  70a4b0269e9 VERSION: Bump version up to 4.12.15...
      from  94c36535bfd WHATSNEW: Add release notes for Samba 4.12.14.

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


- Log -----------------------------------------------------------------
commit 703c6301013f78e80882abfe8375d6a45a176b7f
Author: Karolin Seeger <[email protected]>
Date:   Mon Apr 26 13:38:31 2021 +0200

    VERSION: Disable GIT_SNAPSHOT for the 4.12.15 release.
    
    BUG 14571: CVE-2021-20254: Buffer overrun in sids_to_unixids().
    
    Signed-off-by: Karolin Seeger <[email protected]>

commit 05214a2486061a3bf6c06a70a2016a2994bb37e3
Author: Karolin Seeger <[email protected]>
Date:   Mon Apr 26 13:37:22 2021 +0200

    WHATSNEW: Add release notes for Samba 4.12.15.
    
    Signed-off-by: Karolin Seeger <[email protected]>

commit 6a6a33274c0829bb48c280f65c06213a185bee81
Author: Volker Lendecke <[email protected]>
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
    
    Bug: https://bugzilla.samba.org/show_bug.cgi?id=14571
    
    Signed-off-by: Volker Lendecke <[email protected]>
    Reviewed-by: Jeremy Allison <[email protected]>
    
    (backported from patch from master)
    [backport by [email protected] as master commit
     493f5d6b078e0b0f80d1ef25043e2834cb4fcb87 and
     58e9b62222ad62c81cdf11d704859a227cb2902b creates conflicts
     due to rename of WBC_ID_TYPE_* -> ID_TYPE_*]
    [backport by [email protected] to work around a compiler
     bug showing this error on gcc 5.6 -> 6.x, seen on
     Debian 9 and Ubuntu 16.04 under -O3:
    
     ../../source3/passdb/lookup_sid.c:1246:6: error: assuming
     pointer wraparound does not occur when comparing P +- C1
     with P +- C2 [-Werror=strict-overflow]]

commit 80c8c8552ed7522fadad7a861fda6594b47d02fa
Author: Karolin Seeger <[email protected]>
Date:   Mon Apr 26 13:20:37 2021 +0200

    VERSION: Enable GIT_SNAPSHOT.
    
    Signed-off-by: Karolin Seeger <[email protected]>

commit 70a4b0269e9573560d319591813f4e5ee4513fa2
Author: Stefan Metzmacher <[email protected]>
Date:   Wed Mar 24 11:32:11 2021 +0100

    VERSION: Bump version up to 4.12.15...
    
    GIT_SNAPSHOT is already 'yes'.
    
    Signed-off-by: Stefan Metzmacher <[email protected]>
    (cherry picked from commit deb7b32b4372625211a4d6ba26e3d00223e903ca)

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

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


Changeset truncated at 500 lines:

diff --git a/VERSION b/VERSION
index b3cc915133d..01596d8c954 100644
--- a/VERSION
+++ b/VERSION
@@ -25,7 +25,7 @@
 ########################################################
 SAMBA_VERSION_MAJOR=4
 SAMBA_VERSION_MINOR=12
-SAMBA_VERSION_RELEASE=14
+SAMBA_VERSION_RELEASE=15
 
 ########################################################
 # If a official release has a serious bug              #
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index f3c64a7050c..d77b074f2a7 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,68 @@
+                   ===============================
+                   Release Notes for Samba 4.12.15
+                           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.12.14
+---------------------
+
+o  Volker Lendecke <[email protected]>
+   * 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.12.14
                            March 24, 2021
@@ -55,8 +120,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 82c47b3145b..6887b6ebb62 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,138 @@ 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;
        }
-       err = wbcSidsToUnixIds(wbc_sids, num_not_cached, wbc_ids);
+       /*
+        * gcc versions at least 5.x -> 6.x have a bug
+        * with initializing the wbc_ids[i].type and
+        * wbc_ids[i].id.gid to (uint32_t)-1 in the
+        * same loop when using [-Werror=strict-overflow].
+        * The error is:
+        *
+        * ../../source3/passdb/lookup_sid.c:1246:6: error: assuming
+        * pointer wraparound does not occur when comparing P +- C1
+        * with P +- C2 [-Werror=strict-overflow]
+        *
+        * Doing this loop twice fixes the compiler error.
+        * As wbc_ids_size isn't large this isn't too much
+        * of a performance burden.
+        */
+       for (i=0; i<wbc_ids_size; i++) {
+               wbc_ids[i].id.gid = (uint32_t)-1;
+       }
+       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;


-- 
Samba Shared Repository

Reply via email to