From af6aaf624377b5cc53a827e76a1773a7694e3876 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 8 Sep 2020 13:37:59 -0700 Subject: [PATCH] s3: libsmb: Convert the WINS and broadcast name functions to return size_t * num addresses. Have to do both at once as they are intimately related. The uglyness inside internal_resolve_name() will go away once all the resove_XXX() functions return size_t values. Signed-off-by: Jeremy Allison Reviewed-by: Noel Power --- source3/include/proto.h | 2 +- source3/lib/wins_srv.c | 8 +- source3/libsmb/libsmb_dir.c | 8 +- source3/libsmb/namequery.c | 106 +++++++++++++++++------- source3/libsmb/namequery.h | 12 +-- source3/utils/nmblookup.c | 2 +- source3/winbindd/winbindd_wins_byname.c | 4 +- 7 files changed, 94 insertions(+), 48 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index b91fd8bcad4..95bd9240d9a 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -650,7 +650,7 @@ char **wins_srv_tags(void); void wins_srv_tags_free(char **list); struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip); bool wins_server_tag_ips(const char *tag, TALLOC_CTX *mem_ctx, - struct in_addr **pservers, int *pnum_servers); + struct in_addr **pservers, size_t *pnum_servers); unsigned wins_srv_count_tag(const char *tag); #ifndef ASN1_MAX_OIDS diff --git a/source3/lib/wins_srv.c b/source3/lib/wins_srv.c index 2f28a4de6fb..ea94dc1fa14 100644 --- a/source3/lib/wins_srv.c +++ b/source3/lib/wins_srv.c @@ -331,10 +331,10 @@ struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip) } bool wins_server_tag_ips(const char *tag, TALLOC_CTX *mem_ctx, - struct in_addr **pservers, int *pnum_servers) + struct in_addr **pservers, size_t *pnum_servers) { const char **list; - int i, num_servers; + size_t i, num_servers; struct in_addr *servers; list = lp_wins_server_list(); @@ -348,6 +348,10 @@ bool wins_server_tag_ips(const char *tag, TALLOC_CTX *mem_ctx, struct tagged_ip t_ip; parse_ip(&t_ip, list[i]); if (strcmp(tag, t_ip.tag) == 0) { + /* Wrap check. */ + if (num_servers + 1 < num_servers) { + return false; + } num_servers += 1; } } diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 1f1e3feeadd..6d9eb2316a8 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -560,9 +560,9 @@ SMBC_opendir_ctx(SMBCCTX *context, if (server[0] == (char)0) { - int i; - int count; - int max_lmb_count; + size_t i; + size_t count = 0; + size_t max_lmb_count; struct sockaddr_storage *ip_list; struct sockaddr_storage server_addr; struct user_auth_info *u_info; @@ -649,7 +649,7 @@ SMBC_opendir_ctx(SMBCCTX *context, struct cli_state *cli = NULL; print_sockaddr(addr, sizeof(addr), &ip_list[i]); - DEBUG(99, ("Found master browser %d of %d: %s\n", + DEBUG(99, ("Found master browser %zu of %zu: %s\n", i+1, MAX(count, max_lmb_count), addr)); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f8093a0f6bd..324f391cc4d 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1335,7 +1335,7 @@ struct name_query_state { uint8_t flags; struct sockaddr_storage *addrs; - int num_addrs; + size_t num_addrs; }; static bool name_query_validator(struct packet_struct *p, void *private_data); @@ -1562,6 +1562,10 @@ static bool name_query_validator(struct packet_struct *p, void *private_data) DEBUGADD(2,("%s ",inet_ntoa(ip))); state->addrs[state->num_addrs] = addr; + /* wrap check. */ + if (state->num_addrs + 1 < state->num_addrs) { + return false; + } state->num_addrs += 1; } DEBUGADD(2,(")\n")); @@ -1618,7 +1622,7 @@ static void name_query_done(struct tevent_req *subreq) } NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct sockaddr_storage **addrs, int *num_addrs, + struct sockaddr_storage **addrs, size_t *num_addrs, uint8_t *flags) { struct name_query_state *state = tevent_req_data( @@ -1655,7 +1659,7 @@ NTSTATUS name_query(const char *name, int name_type, const struct sockaddr_storage *to_ss, TALLOC_CTX *mem_ctx, struct sockaddr_storage **addrs, - int *num_addrs, uint8_t *flags) + size_t *num_addrs, uint8_t *flags) { TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev; @@ -1750,17 +1754,17 @@ struct name_queries_state { bool bcast; bool recurse; const struct sockaddr_storage *addrs; - int num_addrs; + size_t num_addrs; int wait_msec; int timeout_msec; struct tevent_req **subreqs; - int num_received; - int num_sent; + size_t num_received; + size_t num_sent; - int received_index; + size_t received_index; struct sockaddr_storage *result_addrs; - int num_result_addrs; + size_t num_result_addrs; uint8_t flags; }; @@ -1776,7 +1780,7 @@ static struct tevent_req *name_queries_send( const char *name, int name_type, bool bcast, bool recurse, const struct sockaddr_storage *addrs, - int num_addrs, int wait_msec, int timeout_msec) + size_t num_addrs, int wait_msec, int timeout_msec) { struct tevent_req *req, *subreq; struct name_queries_state *state; @@ -1837,7 +1841,7 @@ static void name_queries_done(struct tevent_req *subreq) subreq, struct tevent_req); struct name_queries_state *state = tevent_req_data( req, struct name_queries_state); - int i; + size_t i; NTSTATUS status; status = name_query_recv(subreq, state, &state->result_addrs, @@ -1854,6 +1858,11 @@ static void name_queries_done(struct tevent_req *subreq) } TALLOC_FREE(state->subreqs[i]); + /* wrap check. */ + if (state->num_received + 1 < state->num_received) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } state->num_received += 1; if (!NT_STATUS_IS_OK(status)) { @@ -1912,8 +1921,8 @@ static void name_queries_next(struct tevent_req *subreq) static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sockaddr_storage **result_addrs, - int *num_result_addrs, uint8_t *flags, - int *received_index) + size_t *num_result_addrs, uint8_t *flags, + size_t *received_index) { struct name_queries_state *state = tevent_req_data( req, struct name_queries_state); @@ -1944,7 +1953,7 @@ static NTSTATUS name_queries_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct name_resolve_bcast_state { struct sockaddr_storage *addrs; - int num_addrs; + size_t num_addrs; }; static void name_resolve_bcast_done(struct tevent_req *subreq); @@ -1957,7 +1966,7 @@ struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx, struct tevent_req *req, *subreq; struct name_resolve_bcast_state *state; struct sockaddr_storage *bcast_addrs; - int i, num_addrs, num_bcast_addrs; + size_t i, num_addrs, num_bcast_addrs; req = tevent_req_create(mem_ctx, &state, struct name_resolve_bcast_state); @@ -2030,7 +2039,7 @@ static void name_resolve_bcast_done(struct tevent_req *subreq) NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sockaddr_storage **addrs, - int *num_addrs) + size_t *num_addrs) { struct name_resolve_bcast_state *state = tevent_req_data( req, struct name_resolve_bcast_state); @@ -2048,7 +2057,7 @@ NTSTATUS name_resolve_bcast(TALLOC_CTX *mem_ctx, const char *name, int name_type, struct sockaddr_storage **return_iplist, - int *return_count) + size_t *return_count) { TALLOC_CTX *frame = talloc_stackframe(); struct tevent_context *ev; @@ -2078,12 +2087,12 @@ struct query_wins_list_state { const char *name; uint8_t name_type; struct in_addr *servers; - uint32_t num_servers; + size_t num_servers; struct sockaddr_storage server; - uint32_t num_sent; + size_t num_sent; struct sockaddr_storage *addrs; - int num_addrs; + size_t num_addrs; uint8_t flags; }; @@ -2097,7 +2106,7 @@ static void query_wins_list_done(struct tevent_req *subreq); static struct tevent_req *query_wins_list_send( TALLOC_CTX *mem_ctx, struct tevent_context *ev, struct in_addr src_ip, const char *name, uint8_t name_type, - struct in_addr *servers, int num_servers) + struct in_addr *servers, size_t num_servers) { struct tevent_req *req, *subreq; struct query_wins_list_state *state; @@ -2124,10 +2133,18 @@ static struct tevent_req *query_wins_list_send( subreq = name_query_send(state, state->ev, state->name, state->name_type, false, true, &state->server); - state->num_sent += 1; + if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); } + + /* wrap check */ + if (state->num_sent + 1 < state->num_sent) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return tevent_req_post(req, ev); + } + + state->num_sent += 1; if (!tevent_req_set_endtime(subreq, state->ev, timeval_current_ofs(2, 0))) { return tevent_req_post(req, ev); @@ -2184,7 +2201,7 @@ static void query_wins_list_done(struct tevent_req *subreq) static NTSTATUS query_wins_list_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sockaddr_storage **addrs, - int *num_addrs, + size_t *num_addrs, uint8_t *flags) { struct query_wins_list_state *state = tevent_req_data( @@ -2207,11 +2224,11 @@ static NTSTATUS query_wins_list_recv(struct tevent_req *req, } struct resolve_wins_state { - int num_sent; - int num_received; + size_t num_sent; + size_t num_received; struct sockaddr_storage *addrs; - int num_addrs; + size_t num_addrs; uint8_t flags; }; @@ -2228,7 +2245,7 @@ struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx, struct sockaddr_storage src_ss; struct samba_sockaddr src_sa = {0}; struct in_addr src_ip; - int i, num_wins_tags; + size_t i, num_wins_tags; bool ok; req = tevent_req_create(mem_ctx, &state, @@ -2276,13 +2293,18 @@ struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx, num_wins_tags = 0; while (wins_tags[num_wins_tags] != NULL) { + /* wrap check. */ + if (num_wins_tags + 1 < num_wins_tags) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + goto fail; + } num_wins_tags += 1; } for (i=0; inum_received + 1 < state->num_received) { + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + return; + } + state->num_received += 1; if (state->num_received < state->num_sent) { @@ -2370,7 +2398,7 @@ static void resolve_wins_done(struct tevent_req *subreq) NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sockaddr_storage **addrs, - int *num_addrs, uint8_t *flags) + size_t *num_addrs, uint8_t *flags) { struct resolve_wins_state *state = tevent_req_data( req, struct resolve_wins_state); @@ -2399,7 +2427,7 @@ NTSTATUS resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type, struct sockaddr_storage **return_iplist, - int *return_count) + size_t *return_count) { struct tevent_context *ev; struct tevent_req *req; @@ -3390,6 +3418,7 @@ NTSTATUS internal_resolve_name(TALLOC_CTX *ctx, } goto done; } else if (strequal(tok, "wins")) { + size_t wcount = 0; /* don't resolve 1D via WINS */ if (name_type == 0x1D) { continue; @@ -3398,21 +3427,34 @@ NTSTATUS internal_resolve_name(TALLOC_CTX *ctx, name, name_type, &ss_list, - &icount); + &wcount); if (!NT_STATUS_IS_OK(status)) { continue; } + /* + * This uglyness will go away once + * all resolve_XXX() return size_t * + * number of addresses. + */ + icount = (int)wcount; goto done; } else if (strequal(tok, "bcast")) { + size_t bcount = 0; status = name_resolve_bcast( talloc_tos(), name, name_type, &ss_list, - &icount); + &bcount); if (!NT_STATUS_IS_OK(status)) { continue; } + /* + * This uglyness will go away once + * all resolve_XXX() return size_t * + * number of addresses. + */ + icount = (int)bcount; goto done; } else { DBG_ERR("unknown name switch type %s\n", diff --git a/source3/libsmb/namequery.h b/source3/libsmb/namequery.h index 8d22754d248..7b3af3ae3f4 100644 --- a/source3/libsmb/namequery.h +++ b/source3/libsmb/namequery.h @@ -54,38 +54,38 @@ struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx, bool bcast, bool recurse, const struct sockaddr_storage *addr); NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - struct sockaddr_storage **addrs, int *num_addrs, + struct sockaddr_storage **addrs, size_t *num_addrs, uint8_t *flags); NTSTATUS name_query(const char *name, int name_type, bool bcast, bool recurse, const struct sockaddr_storage *to_ss, TALLOC_CTX *mem_ctx, struct sockaddr_storage **addrs, - int *num_addrs, uint8_t *flags); + size_t *num_addrs, uint8_t *flags); struct tevent_req *name_resolve_bcast_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *name, int name_type); NTSTATUS name_resolve_bcast_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sockaddr_storage **addrs, - int *num_addrs); + size_t *num_addrs); NTSTATUS name_resolve_bcast(TALLOC_CTX *mem_ctx, const char *name, int name_type, struct sockaddr_storage **return_iplist, - int *return_count); + size_t *return_count); struct tevent_req *resolve_wins_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, const char *name, int name_type); NTSTATUS resolve_wins_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, struct sockaddr_storage **addrs, - int *num_addrs, uint8_t *flags); + size_t *num_addrs, uint8_t *flags); NTSTATUS resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type, struct sockaddr_storage **return_iplist, - int *return_count); + size_t *return_count); NTSTATUS dns_lookup_list_async(TALLOC_CTX *ctx, size_t num_dns_names, const char **dns_lookup_names, diff --git a/source3/utils/nmblookup.c b/source3/utils/nmblookup.c index 856cc91391a..e9e16109e88 100644 --- a/source3/utils/nmblookup.c +++ b/source3/utils/nmblookup.c @@ -159,7 +159,7 @@ static bool do_node_status(const char *name, static bool query_one(const char *lookup, unsigned int lookup_type) { - int j, count; + size_t j, count = 0; uint8_t flags; struct sockaddr_storage *ip_list=NULL; NTSTATUS status = NT_STATUS_NOT_FOUND; diff --git a/source3/winbindd/winbindd_wins_byname.c b/source3/winbindd/winbindd_wins_byname.c index 8661401331a..0758dcb761f 100644 --- a/source3/winbindd/winbindd_wins_byname.c +++ b/source3/winbindd/winbindd_wins_byname.c @@ -28,7 +28,7 @@ struct winbindd_wins_byname_state { struct tevent_context *ev; struct winbindd_request *request; struct sockaddr_storage *addrs; - int num_addrs; + size_t num_addrs; }; static void winbindd_wins_byname_wins_done(struct tevent_req *subreq); @@ -112,7 +112,7 @@ NTSTATUS winbindd_wins_byname_recv(struct tevent_req *req, req, struct winbindd_wins_byname_state); char *response; NTSTATUS status; - int i; + size_t i; if (tevent_req_is_nterror(req, &status)) { return status; -- 2.47.3