CVE-2013-4408:s3:Ensure LookupRids() replies arrays are range checked.
authorJeremy Allison <jra@samba.org>
Fri, 8 Nov 2013 06:41:22 +0000 (22:41 -0800)
committerKarolin Seeger <kseeger@samba.org>
Thu, 5 Dec 2013 09:54:16 +0000 (10:54 +0100)
Bug: https://bugzilla.samba.org/show_bug.cgi?id=10185

Signed-off-by: Jeremy Allison <jra@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
source3/lib/netapi/group.c
source3/lib/netapi/user.c
source3/rpcclient/cmd_samr.c
source3/utils/net_rpc.c
source3/winbindd/winbindd_msrpc.c
source3/winbindd/winbindd_rpc.c

index 33bc4909655dfe341ef9abf9c774dabefcb69255..b743440966a115745ea6fabe2a19a47b7e97ff02 100644 (file)
@@ -395,6 +395,14 @@ WERROR NetGroupDel_r(struct libnetapi_ctx *ctx,
                werr = ntstatus_to_werror(result);
                goto done;
        }
+       if (names.count != rid_array->count) {
+               werr = WERR_BAD_NET_RESP;
+               goto done;
+       }
+       if (member_types.count != rid_array->count) {
+               werr = WERR_BAD_NET_RESP;
+               goto done;
+       }
        }
 
        for (i=0; i < rid_array->count; i++) {
@@ -1623,6 +1631,14 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx,
                werr = ntstatus_to_werror(result);
                goto done;
        }
+       if (names.count != rid_array->count) {
+               werr = WERR_BAD_NET_RESP;
+               goto done;
+       }
+       if (member_types.count != rid_array->count) {
+               werr = WERR_BAD_NET_RESP;
+               goto done;
+       }
 
        for (i=0; i < names.count; i++) {
 
index 16c0a1f60632cbb92b468f6a109a68d77d5ef68c..1908c86291534c529091e5203190a5e4814fd17a 100644 (file)
@@ -3113,6 +3113,14 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx,
                werr = ntstatus_to_werror(result);
                goto done;
        }
+       if (names.count != rid_array->count) {
+               werr = WERR_BAD_NET_RESP;
+               goto done;
+       }
+       if (types.count != rid_array->count) {
+               werr = WERR_BAD_NET_RESP;
+               goto done;
+       }
 
        for (i=0; i < names.count; i++) {
                status = add_GROUP_USERS_INFO_X_buffer(ctx,
@@ -3714,6 +3722,14 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx,
                werr = ntstatus_to_werror(result);
                goto done;
        }
+       if (names.count != num_rids) {
+               werr = WERR_BAD_NET_RESP;
+               goto done;
+       }
+       if (types.count != num_rids) {
+               werr = WERR_BAD_NET_RESP;
+               goto done;
+       }
 
        for (i=0; i < names.count; i++) {
                status = add_LOCALGROUP_USERS_INFO_X_buffer(ctx,
index 5bc8c0b57b85e0f6206983614fa2a58ace6cdb45..87882c3ce4e9bf9937ef21fd806090fd3c39ba18 100644 (file)
@@ -2223,6 +2223,14 @@ static NTSTATUS cmd_samr_lookup_rids(struct rpc_pipe_client *cli,
                goto done;
 
        /* Display results */
+       if (num_rids != names.count) {
+               status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+               goto done;
+       }
+       if (num_rids != types.count) {
+               status = NT_STATUS_INVALID_NETWORK_RESPONSE;
+               goto done;
+       }
 
        for (i = 0; i < num_rids; i++) {
                printf("rid 0x%x: %s (%d)\n",
index 6a49d673ee2bc178ef9cfcfde2e6e5f135632864..0371c994270792f17d04b473d4c280d9dc25febf 100644 (file)
@@ -2891,7 +2891,12 @@ static NTSTATUS rpc_list_group_members(struct net_context *c,
                if (!NT_STATUS_IS_OK(result)) {
                        return result;
                }
-
+               if (names.count != this_time) {
+                       return NT_STATUS_INVALID_NETWORK_RESPONSE;
+               }
+               if (types.count != this_time) {
+                       return NT_STATUS_INVALID_NETWORK_RESPONSE;
+               }
                /* We only have users as members, but make the output
                   the same as the output of alias members */
 
index 61447d3acf016bf059a92c29aa2ee66d7aff18c5..426d64cf1f930166f3cac5d85e596888d29c8abb 100644 (file)
@@ -744,14 +744,20 @@ static NTSTATUS msrpc_lookup_groupmem(struct winbindd_domain *domain,
                /* Copy result into array.  The talloc system will take
                   care of freeing the temporary arrays later on. */
 
-               if (tmp_names.count != tmp_types.count) {
-                       return NT_STATUS_UNSUCCESSFUL;
+               if (tmp_names.count != num_lookup_rids) {
+                       return NT_STATUS_INVALID_NETWORK_RESPONSE;
+               }
+               if (tmp_types.count != num_lookup_rids) {
+                       return NT_STATUS_INVALID_NETWORK_RESPONSE;
                }
 
                for (r=0; r<tmp_names.count; r++) {
                        if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
                                continue;
                        }
+                       if (total_names >= *num_names) {
+                               break;
+                       }
                        (*names)[total_names] = fill_domain_username_talloc(
                                mem_ctx, domain->name,
                                tmp_names.names[r].string, true);
index 6b88c8413c5dc4d19b568c022e585809b0c0f073..0986d825d9aa4fd19b7bbb50fb270fdecd97407a 100644 (file)
@@ -871,14 +871,20 @@ NTSTATUS rpc_lookup_groupmem(TALLOC_CTX *mem_ctx,
 
        /* Copy result into array.  The talloc system will take
           care of freeing the temporary arrays later on. */
-       if (tmp_names.count != tmp_types.count) {
-               return NT_STATUS_UNSUCCESSFUL;
+       if (tmp_names.count != num_names) {
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
+       }
+       if (tmp_types.count != num_names) {
+               return NT_STATUS_INVALID_NETWORK_RESPONSE;
        }
 
        for (r = 0; r < tmp_names.count; r++) {
                if (tmp_types.ids[r] == SID_NAME_UNKNOWN) {
                        continue;
                }
+               if (total_names >= num_names) {
+                       break;
+               }
                names[total_names] = fill_domain_username_talloc(names,
                                                                 domain_name,
                                                                 tmp_names.names[r].string,