diff --git a/lib/addns/dnsquery.c b/lib/addns/dnsquery.c index 03cadfaef0a..92709234edb 100644 --- a/lib/addns/dnsquery.c +++ b/lib/addns/dnsquery.c @@ -105,6 +105,7 @@ static void ads_dns_lookup_srv_done(struct tevent_req *subreq) for (i=0; iancount; i++) { if (reply->answers[i].rr_type == DNS_QTYPE_SRV) { + /* uint16_t can't wrap here. */ state->num_srvs += 1; } } @@ -153,7 +154,7 @@ static void ads_dns_lookup_srv_done(struct tevent_req *subreq) if (strcmp(srv->hostname, ar->name) != 0) { continue; } - + /* uint16_t can't wrap here. */ tmp = talloc_realloc( state->srvs, srv->ss_s, @@ -200,7 +201,7 @@ NTSTATUS ads_dns_lookup_srv_recv(struct tevent_req *req, NTSTATUS ads_dns_lookup_srv(TALLOC_CTX *ctx, const char *name, struct dns_rr_srv **dclist, - int *numdcs) + size_t *numdcs) { struct tevent_context *ev; struct tevent_req *req; @@ -220,7 +221,7 @@ NTSTATUS ads_dns_lookup_srv(TALLOC_CTX *ctx, } status = ads_dns_lookup_srv_recv(req, ctx, dclist, &num_srvs); if (NT_STATUS_IS_OK(status)) { - *numdcs = num_srvs; /* size_t->int */ + *numdcs = num_srvs; } fail: TALLOC_FREE(ev); @@ -794,7 +795,7 @@ static NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx, { char *name; NTSTATUS status; - int num_srvs = 0; + size_t num_srvs = 0; if ((sitename != NULL) && (strlen(sitename) != 0)) { name = talloc_asprintf(ctx, "%s._tcp.%s._sites.%s._msdcs.%s", @@ -826,7 +827,11 @@ static NTSTATUS ads_dns_query_internal(TALLOC_CTX *ctx, status = ads_dns_lookup_srv(ctx, name, dclist, &num_srvs); done: - *numdcs = num_srvs; /* automatic conversion size_t->int */ + /* check overflow size_t -> int */ + if ((int)num_srvs < 0) { + return NT_STATUS_INVALID_PARAMETER; + } + *numdcs = num_srvs; return status; } diff --git a/lib/addns/dnsquery.h b/lib/addns/dnsquery.h index 3f8cc13983b..ddcafeb3936 100644 --- a/lib/addns/dnsquery.h +++ b/lib/addns/dnsquery.h @@ -36,7 +36,7 @@ NTSTATUS ads_dns_lookup_srv_recv(struct tevent_req *req, NTSTATUS ads_dns_lookup_srv(TALLOC_CTX *ctx, const char *name, struct dns_rr_srv **dclist, - int *numdcs); + size_t *numdcs); struct tevent_req *ads_dns_lookup_ns_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *name); diff --git a/source4/libcli/resolve/dns_ex.c b/source4/libcli/resolve/dns_ex.c index a2e5551ea26..0bb3ba02287 100644 --- a/source4/libcli/resolve/dns_ex.c +++ b/source4/libcli/resolve/dns_ex.c @@ -268,13 +268,13 @@ done: static struct dns_records_container get_srv_records(TALLOC_CTX *mem_ctx, const char* name) { - struct dns_records_container ret; + struct dns_records_container ret = {0}; char **addrs = NULL; struct dns_rr_srv *dclist; NTSTATUS status; - uint32_t total; - int i; - int count; + size_t total; + size_t i; + size_t count = 0; memset(&ret, 0, sizeof(struct dns_records_container)); /* this is the blocking call we are going to lots of trouble @@ -303,6 +303,13 @@ static struct dns_records_container get_srv_records(TALLOC_CTX *mem_ctx, } c = get_a_aaaa_records(mem_ctx, tmp_str, dclist[i].port); + + /* wrap check */ + if (total + c.count < total) { + /* possibly could just break here instead? */ + TALLOC_FREE(addrs); + return ret; + } total += c.count; if (addrs == NULL) { addrs = c.list;