@@ -20,14 +20,16 @@
static int
merge_words (char ** dst, char * word, int space)
{
- char * p;
+ char * p = *dst;
int len;
len = strlen(*dst) + strlen(word) + space;
*dst = REALLOC(*dst, len + 1);
- if (!*dst)
+ if (!*dst) {
+ free(p);
return 1;
+ }
p = *dst;
@@ -395,7 +395,7 @@ out:
static int
dump_config (void)
{
- char * c;
+ char * c, * tmp = NULL;
char * reply;
unsigned int maxlen = 256;
int again = 1;
@@ -403,9 +403,12 @@ dump_config (void)
reply = MALLOC(maxlen);
while (again) {
- if (!reply)
+ if (!reply) {
+ if (tmp)
+ free(tmp);
return 1;
- c = reply;
+ }
+ c = tmp = reply;
c += snprint_defaults(c, reply + maxlen - c);
again = ((c - reply) == maxlen);
if (again) {
@@ -26,11 +26,14 @@
#define REALLOC_REPLY(r, a, m) \
do { \
if ((a)) { \
+ char *tmp = (r); \
(r) = REALLOC((r), (m) * 2); \
if ((r)) { \
memset((r) + (m), 0, (m)); \
(m) *= 2; \
} \
+ else \
+ free(tmp); \
} \
} while (0)
@@ -173,7 +176,7 @@ show_config (char ** r, int * len)
unsigned int maxlen = INITIAL_REPLY_LEN;
int again = 1;
- reply = MALLOC(maxlen);
+ c = reply = MALLOC(maxlen);
while (again) {
if (!reply)
@@ -181,54 +184,29 @@ show_config (char ** r, int * len)
c = reply;
c += snprint_defaults(c, reply + maxlen - c);
again = ((c - reply) == maxlen);
- if (again) {
- reply = REALLOC(reply, maxlen * 2);
- if (!reply)
- return 1;
- memset(reply + maxlen, 0, maxlen);
- maxlen *= 2;
+ REALLOC_REPLY(reply, again, maxlen);
+ if (again)
continue;
- }
c += snprint_blacklist(c, reply + maxlen - c);
again = ((c - reply) == maxlen);
- if (again) {
- reply = REALLOC(reply, maxlen * 2);
- if (!reply)
- return 1;
- memset(reply + maxlen, 0, maxlen);
- maxlen *= 2;
+ REALLOC_REPLY(reply, again, maxlen);
+ if (again)
continue;
- }
c += snprint_blacklist_except(c, reply + maxlen - c);
again = ((c - reply) == maxlen);
- if (again) {
- reply = REALLOC(reply, maxlen * 2);
- if (!reply)
- return 1;
- memset(reply + maxlen, 0, maxlen);
- maxlen *= 2;
+ REALLOC_REPLY(reply, again, maxlen);
+ if (again)
continue;
- }
c += snprint_hwtable(c, reply + maxlen - c, conf->hwtable);
again = ((c - reply) == maxlen);
- if (again) {
- reply = REALLOC(reply, maxlen * 2);
- if (!reply)
- return 1;
- memset(reply + maxlen, 0, maxlen);
- maxlen *= 2;
+ REALLOC_REPLY(reply, again, maxlen);
+ if (again)
continue;
- }
c += snprint_overrides(c, reply + maxlen - c, conf->overrides);
again = ((c - reply) == maxlen);
- if (again) {
- reply = REALLOC(reply, maxlen * 2);
- if (!reply)
- return 1;
- memset(reply + maxlen, 0, maxlen);
- maxlen *= 2;
+ REALLOC_REPLY(reply, again, maxlen);
+ if (again)
continue;
- }
if (VECTOR_SIZE(conf->mptable) > 0) {
c += snprint_mptable(c, reply + maxlen - c,
conf->mptable);
@@ -65,6 +65,10 @@ static void new_client(int ux_sock)
return;
c = (struct client *)MALLOC(sizeof(*c));
+ if (!c) {
+ close(fd);
+ return;
+ }
memset(c, 0, sizeof(*c));
INIT_LIST_HEAD(&c->node);
c->fd = fd;
@@ -151,6 +155,7 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
sigdelset(&mask, SIGHUP);
sigdelset(&mask, SIGUSR1);
while (1) {
+ struct pollfd *new;
struct client *c, *tmp;
int i, poll_count, num_clients;
@@ -168,7 +173,19 @@ void * uxsock_listen(uxsock_trigger_fn uxsock_trigger, void * trigger_data)
list_for_each_entry(c, &clients, node) {
num_clients++;
}
- polls = REALLOC(polls, (1+num_clients) * sizeof(*polls));
+ new = REALLOC(polls, (1+num_clients) * sizeof(*polls));
+ /* If we can't allocate poliing space for the new client,
+ * close it */
+ if (!new) {
+ if (!num_clients) {
+ condlog(1, "can't listen for new clients");
+ return NULL;
+ }
+ dead_client(list_entry(clients.prev,
+ typeof(struct client), node));
+ }
+ else
+ polls = new;
polls[0].fd = ux_sock;
polls[0].events = POLLIN;
When realloc fails, it doesn't free the existing memory. In many places, multipath was just forgetting about that that memory. It needs to free up the existing memory, or to reset back to using it. Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com> --- libmultipath/dmparser.c | 6 ++++-- multipath/main.c | 9 ++++++--- multipathd/cli_handlers.c | 50 +++++++++++++---------------------------------- multipathd/uxlsnr.c | 19 +++++++++++++++++- 4 files changed, 42 insertions(+), 42 deletions(-)