From patchwork Fri May 15 23:14:05 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Marzinski X-Patchwork-Id: 6417581 X-Patchwork-Delegate: christophe.varoqui@free.fr Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 0E98E9F1CC for ; Fri, 15 May 2015 23:18:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 196E32058C for ; Fri, 15 May 2015 23:18:32 +0000 (UTC) Received: from mx4-phx2.redhat.com (mx4-phx2.redhat.com [209.132.183.25]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7413F20582 for ; Fri, 15 May 2015 23:18:30 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx4-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id t4FNEu3x019878; Fri, 15 May 2015 19:14:56 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id t4FNEIO0029429 for ; Fri, 15 May 2015 19:14:18 -0400 Received: from redhat.com (octiron.msp.redhat.com [10.15.80.209]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id t4FNEH0L008602; Fri, 15 May 2015 19:14:17 -0400 Received: by redhat.com (sSMTP sendmail emulation); Fri, 15 May 2015 18:14:17 -0500 From: "Benjamin Marzinski" To: device-mapper development Date: Fri, 15 May 2015 18:14:05 -0500 Message-Id: <1431731653-3892-3-git-send-email-bmarzins@redhat.com> In-Reply-To: <1431731653-3892-1-git-send-email-bmarzins@redhat.com> References: <1431731653-3892-1-git-send-email-bmarzins@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-loop: dm-devel@redhat.com Cc: Christophe Varoqui Subject: [dm-devel] [PATCH 02/10] fix memory leaks on realloc failures X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 --- libmultipath/dmparser.c | 6 ++++-- multipath/main.c | 9 ++++++--- multipathd/cli_handlers.c | 50 +++++++++++++---------------------------------- multipathd/uxlsnr.c | 19 +++++++++++++++++- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/libmultipath/dmparser.c b/libmultipath/dmparser.c index 2562ba1..2209b2d 100644 --- a/libmultipath/dmparser.c +++ b/libmultipath/dmparser.c @@ -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; diff --git a/multipath/main.c b/multipath/main.c index f62dcb1..d761621 100644 --- a/multipath/main.c +++ b/multipath/main.c @@ -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) { diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c index dc96c45..305cd7f 100644 --- a/multipathd/cli_handlers.c +++ b/multipathd/cli_handlers.c @@ -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); diff --git a/multipathd/uxlsnr.c b/multipathd/uxlsnr.c index 61ba49a..64bd35c 100644 --- a/multipathd/uxlsnr.c +++ b/multipathd/uxlsnr.c @@ -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;