[Pkg-samba-maint] [samba] 15/26: CVE-2013-4408:s3:Ensure LookupSids replies arrays are range checked.
Ivo De Decker
idd-guest at moszumanska.debian.org
Mon Dec 9 22:22:16 UTC 2013
This is an automated email from the git hooks/post-receive script.
idd-guest pushed a commit to branch samba_4.1
in repository samba.
commit ca5d6f5eed28350a7d0a5179e2d4ca31d0069959
Author: Jeremy Allison <jra at samba.org>
Date: Thu Nov 7 20:38:01 2013 -0800
CVE-2013-4408:s3:Ensure LookupSids replies arrays are range checked.
Bug: https://bugzilla.samba.org/show_bug.cgi?id=10185
Signed-off-by: Stefan Metzmacher <metze at samba.org>
Signed-off-by: Jeremy Allison <jra at samba.org>
---
nsswitch/libwbclient/wbc_sid.c | 7 +++++++
nsswitch/wbinfo.c | 23 ++++++++++++++++++++---
source3/rpc_client/cli_lsarpc.c | 17 ++++++++++++++++-
source3/rpcclient/cmd_lsarpc.c | 7 +++++--
source3/winbindd/wb_lookupsids.c | 3 +++
source3/winbindd/winbindd_rpc.c | 32 ++++++++++++++++++++++++++++++++
source4/libcli/util/clilsa.c | 16 +++++++++++++++-
source4/winbind/wb_async_helpers.c | 13 ++++++++++++-
8 files changed, 110 insertions(+), 8 deletions(-)
diff --git a/nsswitch/libwbclient/wbc_sid.c b/nsswitch/libwbclient/wbc_sid.c
index bab6933..82ac339 100644
--- a/nsswitch/libwbclient/wbc_sid.c
+++ b/nsswitch/libwbclient/wbc_sid.c
@@ -421,6 +421,13 @@ wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids,
for (i=0; i<num_names; i++) {
names[i].domain_index = strtoul(p, &q, 10);
+ if (names[i].domain_index < 0) {
+ goto wbc_err_invalid;
+ }
+ if (names[i].domain_index >= num_domains) {
+ goto wbc_err_invalid;
+ }
+
if (*q != ' ') {
goto wbc_err_invalid;
}
diff --git a/nsswitch/wbinfo.c b/nsswitch/wbinfo.c
index 17977ed..3f0310a 100644
--- a/nsswitch/wbinfo.c
+++ b/nsswitch/wbinfo.c
@@ -1391,11 +1391,28 @@ static bool wbinfo_lookup_sids(const char *arg)
}
for (i=0; i<num_sids; i++) {
+ const char *domain = NULL;
+
wbcSidToStringBuf(&sids[i], sidstr, sizeof(sidstr));
- d_printf("%s -> %s\\%s %d\n", sidstr,
- domains[names[i].domain_index].short_name,
- names[i].name, names[i].type);
+ if (names[i].domain_index >= num_domains) {
+ domain = "<none>";
+ } else if (names[i].domain_index < 0) {
+ domain = "<none>";
+ } else {
+ domain = domains[names[i].domain_index].short_name;
+ }
+
+ if (names[i].type == WBC_SID_NAME_DOMAIN) {
+ d_printf("%s -> %s %d\n", sidstr,
+ domain,
+ names[i].type);
+ } else {
+ d_printf("%s -> %s%c%s %d\n", sidstr,
+ domain,
+ winbind_separator(),
+ names[i].name, names[i].type);
+ }
}
wbcFreeMemory(names);
wbcFreeMemory(domains);
diff --git a/source3/rpc_client/cli_lsarpc.c b/source3/rpc_client/cli_lsarpc.c
index 126f370..7cadd6e 100644
--- a/source3/rpc_client/cli_lsarpc.c
+++ b/source3/rpc_client/cli_lsarpc.c
@@ -279,11 +279,26 @@ static NTSTATUS dcerpc_lsa_lookup_sids_noalloc(struct dcerpc_binding_handle *h,
for (i = 0; i < num_sids; i++) {
const char *name, *dom_name;
- uint32_t dom_idx = lsa_names.names[i].sid_index;
+ uint32_t dom_idx;
+
+ if (i >= lsa_names.count) {
+ *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ return status;
+ }
+
+ dom_idx = lsa_names.names[i].sid_index;
/* Translate optimised name through domain index array */
if (dom_idx != 0xffffffff) {
+ if (ref_domains == NULL) {
+ *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ return status;
+ }
+ if (dom_idx >= ref_domains->count) {
+ *presult = NT_STATUS_INVALID_NETWORK_RESPONSE;
+ return status;
+ }
dom_name = ref_domains->domains[dom_idx].name.string;
name = lsa_names.names[i].name.string;
diff --git a/source3/rpcclient/cmd_lsarpc.c b/source3/rpcclient/cmd_lsarpc.c
index cbc089f..a7ee4e4 100644
--- a/source3/rpcclient/cmd_lsarpc.c
+++ b/source3/rpcclient/cmd_lsarpc.c
@@ -450,7 +450,7 @@ static NTSTATUS cmd_lsa_lookup_sids3(struct rpc_pipe_client *cli,
NTSTATUS status = NT_STATUS_UNSUCCESSFUL, result;
int i;
struct lsa_SidArray sids;
- struct lsa_RefDomainList *domains;
+ struct lsa_RefDomainList *domains = NULL;
struct lsa_TransNameArray2 names;
uint32_t count = 0;
struct dcerpc_binding_handle *b = cli->binding_handle;
@@ -506,9 +506,12 @@ static NTSTATUS cmd_lsa_lookup_sids3(struct rpc_pipe_client *cli,
/* Print results */
- for (i = 0; i < count; i++) {
+ for (i = 0; i < names.count; i++) {
fstring sid_str;
+ if (i >= sids.num_sids) {
+ break;
+ }
sid_to_fstring(sid_str, sids.sids[i].sid);
printf("%s %s (%d)\n", sid_str,
names.names[i].name.string,
diff --git a/source3/winbindd/wb_lookupsids.c b/source3/winbindd/wb_lookupsids.c
index 2c4ebda..e10d511 100644
--- a/source3/winbindd/wb_lookupsids.c
+++ b/source3/winbindd/wb_lookupsids.c
@@ -402,6 +402,9 @@ static bool wb_lookupsids_move_name(struct lsa_RefDomainList *src_domains,
uint32_t src_domain_index, dst_domain_index;
src_domain_index = src_name->sid_index;
+ if (src_domain_index >= src_domains->count) {
+ return false;
+ }
src_domain = &src_domains->domains[src_domain_index];
if (!wb_lookupsids_find_dom_idx(
diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c
index 44deeb0..7345ea7 100644
--- a/source3/winbindd/winbindd_rpc.c
+++ b/source3/winbindd/winbindd_rpc.c
@@ -1084,6 +1084,10 @@ static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_ERR(result)) {
return result;
}
+ if (sids->num_sids != lsa_names2.count) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
names = talloc_zero(mem_ctx, struct lsa_TransNameArray);
if (names == NULL) {
return NT_STATUS_NO_MEMORY;
@@ -1099,6 +1103,16 @@ static NTSTATUS rpc_try_lookup_sids3(TALLOC_CTX *mem_ctx,
names->names[i].name.string = talloc_move(
names->names, &lsa_names2.names[i].name.string);
names->names[i].sid_index = lsa_names2.names[i].sid_index;
+
+ if (names->names[i].sid_index == UINT32_MAX) {
+ continue;
+ }
+ if ((*pdomains) == NULL) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ if (names->names[i].sid_index >= (*pdomains)->count) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
}
*pnames = names;
return result;
@@ -1114,6 +1128,7 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
struct rpc_pipe_client *cli = NULL;
struct policy_handle lsa_policy;
uint32_t count;
+ uint32_t i;
NTSTATUS status, result;
status = cm_connect_lsat(domain, mem_ctx, &cli, &lsa_policy);
@@ -1140,6 +1155,23 @@ NTSTATUS rpc_lookup_sids(TALLOC_CTX *mem_ctx,
if (NT_STATUS_IS_ERR(result)) {
return result;
}
+
+ if (sids->num_sids != names->count) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+
+ for (i=0; i < names->count; i++) {
+ if (names->names[i].sid_index == UINT32_MAX) {
+ continue;
+ }
+ if ((*pdomains) == NULL) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ if (names->names[i].sid_index >= (*pdomains)->count) {
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ }
+
*pnames = names;
return result;
}
diff --git a/source4/libcli/util/clilsa.c b/source4/libcli/util/clilsa.c
index 812f953..cc0dae5 100644
--- a/source4/libcli/util/clilsa.c
+++ b/source4/libcli/util/clilsa.c
@@ -260,7 +260,21 @@ NTSTATUS smblsa_lookup_sid(struct smbcli_state *cli,
}
if (names.count != 1) {
talloc_free(mem_ctx2);
- return NT_STATUS_UNSUCCESSFUL;
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ if (domains == NULL) {
+ talloc_free(mem_ctx2);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ if (domains->count != 1) {
+ talloc_free(mem_ctx2);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
+ }
+ if (names.names[0].sid_index != UINT32_MAX &&
+ names.names[0].sid_index >= domains->count)
+ {
+ talloc_free(mem_ctx2);
+ return NT_STATUS_INVALID_NETWORK_RESPONSE;
}
(*name) = talloc_asprintf(mem_ctx, "%s\\%s",
diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c
index 2af8567..e3de2eb 100644
--- a/source4/winbind/wb_async_helpers.c
+++ b/source4/winbind/wb_async_helpers.c
@@ -122,6 +122,12 @@ static void lsa_lookupsids_recv_names(struct tevent_req *subreq)
return;
}
+ if (state->names.count != state->num_sids) {
+ composite_error(state->ctx,
+ NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return;
+ }
+
state->result = talloc_array(state, struct wb_sid_object *,
state->num_sids);
if (composite_nomem(state->result, state->ctx)) return;
@@ -142,9 +148,14 @@ static void lsa_lookupsids_recv_names(struct tevent_req *subreq)
continue;
}
+ if (domains == NULL) {
+ composite_error(state->ctx,
+ NT_STATUS_INVALID_NETWORK_RESPONSE);
+ return;
+ }
if (name->sid_index >= domains->count) {
composite_error(state->ctx,
- NT_STATUS_INVALID_PARAMETER);
+ NT_STATUS_INVALID_NETWORK_RESPONSE);
return;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-samba/samba.git
More information about the Pkg-samba-maint
mailing list