lib/cache_mngr.c: avoid memleak if realloc fails

foo = realloc(foo, ...) is almost always a bug - the only exceptions
being if (a) one just exits the process in case of failure or (b) if one
has made a copy of the foo pointer before the realloc call, and takes
care to either reinstate it afterwards or free() it and make sure that
the data structure is updated to handle foo now being NULL (in this case
for example setting ->cm_nassocs to 0). (a) is not an option in
libraries, and (b) is more cumbersome than just doing it the canonical
way: use local variables for the new pointer and size, and only install
them when realloc succeeds.
This commit is contained in:
Rasmus Villemoes 2017-06-08 10:59:12 +02:00
parent 32d13c0058
commit 3cbfa90c9c

View File

@ -317,15 +317,18 @@ retry:
break;
if (i >= mngr->cm_nassocs) {
mngr->cm_nassocs += NASSOC_EXPAND;
mngr->cm_assocs = realloc(mngr->cm_assocs,
mngr->cm_nassocs *
sizeof(struct nl_cache_assoc));
if (mngr->cm_assocs == NULL)
struct nl_cache_assoc *cm_assocs;
int cm_nassocs = mngr->cm_nassocs + NASSOC_EXPAND;
cm_assocs = realloc(mngr->cm_assocs,
cm_nassocs * sizeof(struct nl_cache_assoc));
if (cm_assocs == NULL)
return -NLE_NOMEM;
memset(mngr->cm_assocs + (mngr->cm_nassocs - NASSOC_EXPAND), 0,
memset(cm_assocs + mngr->cm_nassocs, 0,
NASSOC_EXPAND * sizeof(struct nl_cache_assoc));
mngr->cm_assocs = cm_assocs;
mngr->cm_nassocs = cm_nassocs;
NL_DBG(1, "Increased capacity of cache manager %p " \
"to %d\n", mngr, mngr->cm_nassocs);