From patchwork Fri May 15 23:14:13 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Marzinski X-Patchwork-Id: 6417571 X-Patchwork-Delegate: christophe.varoqui@free.fr Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 432E5C0432 for ; Fri, 15 May 2015 23:18:32 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 11E4F20588 for ; Fri, 15 May 2015 23:18:31 +0000 (UTC) Received: from mx6-phx2.redhat.com (mx6-phx2.redhat.com [209.132.183.39]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 133DE201F2 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 mx6-phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t4FNExwv009508; Fri, 15 May 2015 19:14:59 -0400 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id t4FNEWOZ029666 for ; Fri, 15 May 2015 19:14:32 -0400 Received: from redhat.com (octiron.msp.redhat.com [10.15.80.209]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with SMTP id t4FNEU6Y005538; Fri, 15 May 2015 19:14:31 -0400 Received: by redhat.com (sSMTP sendmail emulation); Fri, 15 May 2015 18:14:30 -0500 From: "Benjamin Marzinski" To: device-mapper development Date: Fri, 15 May 2015 18:14:13 -0500 Message-Id: <1431731653-3892-11-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.26 X-loop: dm-devel@redhat.com Cc: Christophe Varoqui Subject: [dm-devel] [PATCH 10/10] resize reply buffer for mutipathd help message 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=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, 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 Unlike the other reply messages from multipathd, the generic help message code couldn't resize the buffer, and the reply had grown too big for the initial buffer size. This was causing memory corruption and crashing multipathd instead of printing a help message. This patch increases the size of the initial reply buffer, and makes the help message code able to resize the buffer so this doesn't happen in the future. Signed-off-by: Benjamin Marzinski --- multipathd/cli.c | 88 +++++++++++++++++++++++++++++++++-------------- multipathd/cli.h | 16 ++++++++- multipathd/cli_handlers.c | 14 -------- 3 files changed, 78 insertions(+), 40 deletions(-) diff --git a/multipathd/cli.c b/multipathd/cli.c index acc4249..8d26956 100644 --- a/multipathd/cli.c +++ b/multipathd/cli.c @@ -320,52 +320,90 @@ alloc_handlers (void) } static int -genhelp_sprint_aliases (char * reply, vector keys, struct key * refkw) +genhelp_sprint_aliases (char * reply, int maxlen, vector keys, + struct key * refkw) { - int i, fwd = 0; + int i, len = 0; struct key * kw; - vector_foreach_slot (keys, kw, i) - if (kw->code == refkw->code && kw != refkw) - fwd += sprintf(reply, "|%s", kw->str); + vector_foreach_slot (keys, kw, i) { + if (kw->code == refkw->code && kw != refkw) { + len += snprintf(reply + len, maxlen - len, + "|%s", kw->str); + if (len >= maxlen) + return len; + } + } - return fwd; + return len; } -static char * -genhelp_handler (void) -{ +static int +do_genhelp(char *reply, int maxlen) { + int len = 0; int i, j; unsigned long fp; struct handler * h; struct key * kw; - char * reply; - char * p; - - reply = MALLOC(INITIAL_REPLY_LEN); - if (!reply) - return NULL; - - p = reply; - p += sprintf(p, VERSION_STRING); - p += sprintf(p, "CLI commands reference:\n"); + len += snprintf(reply + len, maxlen - len, VERSION_STRING); + if (len >= maxlen) + goto out; + len += snprintf(reply + len, maxlen - len, "CLI commands reference:\n"); + if (len >= maxlen) + goto out; vector_foreach_slot (handlers, h, i) { fp = h->fingerprint; vector_foreach_slot (keys, kw, j) { if ((kw->code & fp)) { fp -= kw->code; - p += sprintf(p, " %s", kw->str); - p += genhelp_sprint_aliases(p, keys, kw); - - if (kw->has_param) - p += sprintf(p, " $%s", kw->str); + len += snprintf(reply + len , maxlen - len, + " %s", kw->str); + if (len >= maxlen) + goto out; + len += genhelp_sprint_aliases(reply + len, + maxlen - len, + keys, kw); + if (len >= maxlen) + goto out; + + if (kw->has_param) { + len += snprintf(reply + len, + maxlen - len, + " $%s", kw->str); + if (len >= maxlen) + goto out; + } } } - p += sprintf(p, "\n"); + len += snprintf(reply + len, maxlen - len, "\n"); + if (len >= maxlen) + goto out; } +out: + return len; +} + +static char * +genhelp_handler (void) +{ + char * reply; + char * p = NULL; + int maxlen = INITIAL_REPLY_LEN; + int again = 1; + + reply = MALLOC(maxlen); + + while (again) { + if (!reply) + return NULL; + p = reply; + p += do_genhelp(reply, maxlen); + again = ((p - reply) >= maxlen); + REALLOC_REPLY(reply, again, maxlen); + } return reply; } diff --git a/multipathd/cli.h b/multipathd/cli.h index 09fdc68..2e0e1da 100644 --- a/multipathd/cli.h +++ b/multipathd/cli.h @@ -71,7 +71,21 @@ enum { #define SETPRSTATUS (1UL << __SETPRSTATUS) #define UNSETPRSTATUS (1UL << __UNSETPRSTATUS) -#define INITIAL_REPLY_LEN 1100 +#define INITIAL_REPLY_LEN 1200 + +#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) struct key { char * str; diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c index 305cd7f..8cde810 100644 --- a/multipathd/cli_handlers.c +++ b/multipathd/cli_handlers.c @@ -23,20 +23,6 @@ #include "cli.h" #include "uevent.h" -#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) - int show_paths (char ** r, int * len, struct vectors * vecs, char * style) {