]> git.samba.org - metze/samba/wip.git/commitdiff
CVE-2023-4154 libcli/security: prepare security_descriptor_acl_add() to place the...
authorStefan Metzmacher <metze@samba.org>
Thu, 16 Mar 2023 09:00:11 +0000 (10:00 +0100)
committerJule Anger <janger@samba.org>
Mon, 9 Oct 2023 20:16:08 +0000 (22:16 +0200)
Often it is important to insert an ace at a specific position in the
ACL. As a default we still append by default by using -1, which is the
generic version of passing the number of existing aces.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15424

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
(cherry picked from commit c3cb915a67aff6739b72b86d7d139609df309ada)

libcli/security/security_descriptor.c

index 64c2d027876a21a31095f59920f669d76218ac8e..8657c79736420f8cc5116a98cb7b7bf73bb3e5c0 100644 (file)
@@ -267,9 +267,11 @@ NTSTATUS security_descriptor_for_client(TALLOC_CTX *mem_ctx,
 
 static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
                                            bool add_to_sacl,
-                                           const struct security_ace *ace)
+                                           const struct security_ace *ace,
+                                           ssize_t _idx)
 {
        struct security_acl *acl = NULL;
+       ssize_t idx;
 
        if (add_to_sacl) {
                acl = sd->sacl;
@@ -288,15 +290,28 @@ static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
                acl->aces     = NULL;
        }
 
+       if (_idx < 0) {
+               idx = (acl->num_aces + 1) + _idx;
+       } else {
+               idx = _idx;
+       }
+
+       if (idx < 0) {
+               return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
+       } else if (idx > acl->num_aces) {
+               return NT_STATUS_ARRAY_BOUNDS_EXCEEDED;
+       }
+
        acl->aces = talloc_realloc(acl, acl->aces,
                                   struct security_ace, acl->num_aces+1);
        if (acl->aces == NULL) {
                return NT_STATUS_NO_MEMORY;
        }
 
-       acl->aces[acl->num_aces] = *ace;
+       ARRAY_INSERT_ELEMENT(acl->aces, acl->num_aces, *ace, idx);
+       acl->num_aces++;
 
-       switch (acl->aces[acl->num_aces].type) {
+       switch (acl->aces[idx].type) {
        case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT:
        case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT:
        case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT:
@@ -307,8 +322,6 @@ static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
                break;
        }
 
-       acl->num_aces++;
-
        if (add_to_sacl) {
                sd->sacl = acl;
                sd->type |= SEC_DESC_SACL_PRESENT;
@@ -327,7 +340,7 @@ static NTSTATUS security_descriptor_acl_add(struct security_descriptor *sd,
 NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd,
                                      const struct security_ace *ace)
 {
-       return security_descriptor_acl_add(sd, true, ace);
+       return security_descriptor_acl_add(sd, true, ace, -1);
 }
 
 /*
@@ -337,7 +350,7 @@ NTSTATUS security_descriptor_sacl_add(struct security_descriptor *sd,
 NTSTATUS security_descriptor_dacl_add(struct security_descriptor *sd,
                                      const struct security_ace *ace)
 {
-       return security_descriptor_acl_add(sd, false, ace);
+       return security_descriptor_acl_add(sd, false, ace, -1);
 }
 
 /*