authd: allocate the correct size of auth_client_data

If there are holes in the auth_providers ID numbers, the array allocated
based on list length won't be large enough to handle all the IDs.

(auth->data could be converted to a dlink_list)
This commit is contained in:
Simon Arlott 2016-05-01 11:38:32 +01:00
parent a5f52774bb
commit 075d4d569e
No known key found for this signature in database
GPG key ID: C8975F2043CA5D24

View file

@ -59,7 +59,7 @@ rb_dictionary *auth_clients;
rb_dlink_list auth_providers; rb_dlink_list auth_providers;
static rb_dlink_list free_pids; static rb_dlink_list free_pids;
static uint32_t pid; static uint32_t allocated_pids;
static struct ev_entry *timeout_ev; static struct ev_entry *timeout_ev;
/* Initalise all providers */ /* Initalise all providers */
@ -123,15 +123,13 @@ load_provider(struct auth_provider *provider)
} }
else else
{ {
if(pid == UINT32_MAX) if(allocated_pids == MAX_PROVIDERS || allocated_pids == UINT32_MAX)
{ {
/* If this happens, well, I don't know what to say. Probably a bug.
* In any case, UINT32_MAX is a special sentinel. */
warn_opers(L_WARN, "Cannot load additional provider, max reached!"); warn_opers(L_WARN, "Cannot load additional provider, max reached!");
return; return;
} }
provider->id = pid++; provider->id = allocated_pids++;
} }
if(provider->opt_handlers != NULL) if(provider->opt_handlers != NULL)
@ -215,7 +213,7 @@ provider_done(struct auth_client *auth, uint32_t id)
lrb_assert(is_provider_running(auth, id)); lrb_assert(is_provider_running(auth, id));
lrb_assert(id != UINT32_MAX); lrb_assert(id != UINT32_MAX);
lrb_assert(id <= pid); lrb_assert(id < allocated_pids);
set_provider_done(auth, id); set_provider_done(auth, id);
@ -312,11 +310,7 @@ start_auth(const char *cid, const char *l_ip, const char *l_port, const char *c_
rb_strlcpy(auth->hostname, "*", sizeof(auth->hostname)); rb_strlcpy(auth->hostname, "*", sizeof(auth->hostname));
rb_strlcpy(auth->username, "*", sizeof(auth->username)); rb_strlcpy(auth->username, "*", sizeof(auth->username));
/* FIXME this is unsafe, the list being allocated needs to auth->data = rb_malloc(allocated_pids * sizeof(struct auth_client_data));
* support the maximum PID allocated, not just the current
* length of auth_providers */
auth->data = rb_malloc(rb_dlink_list_length(&auth_providers) *
sizeof(struct auth_client_data));
auth->providers_starting = true; auth->providers_starting = true;
RB_DLINK_FOREACH(ptr, auth_providers.head) RB_DLINK_FOREACH(ptr, auth_providers.head)