From patchwork Thu Sep 3 00:32:13 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Christophe Dubois X-Patchwork-Id: 32861 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by bilbo.ozlabs.org (Postfix) with ESMTPS id 263D5B6F34 for ; Thu, 3 Sep 2009 10:47:29 +1000 (EST) Received: from localhost ([127.0.0.1]:55681 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Mj0U0-0005Zw-DT for incoming@patchwork.ozlabs.org; Wed, 02 Sep 2009 20:47:24 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Mj0Ta-0005WY-8n for qemu-devel@nongnu.org; Wed, 02 Sep 2009 20:46:58 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Mj0TV-0005UM-NH for qemu-devel@nongnu.org; Wed, 02 Sep 2009 20:46:58 -0400 Received: from [199.232.76.173] (port=33874 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Mj0TV-0005UJ-K4 for qemu-devel@nongnu.org; Wed, 02 Sep 2009 20:46:53 -0400 Received: from smtp6-g21.free.fr ([212.27.42.6]:51900) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1Mj0FR-0003Wz-3o for qemu-devel@nongnu.org; Wed, 02 Sep 2009 20:32:21 -0400 Received: from smtp6-g21.free.fr (localhost [127.0.0.1]) by smtp6-g21.free.fr (Postfix) with ESMTP id 5FF99E08060; Thu, 3 Sep 2009 02:32:16 +0200 (CEST) Received: from localhost.localdomain (unknown [78.235.240.156]) by smtp6-g21.free.fr (Postfix) with ESMTP id 2AF62E08017; Thu, 3 Sep 2009 02:32:14 +0200 (CEST) From: Jean-Christophe DUBOIS To: qemu-devel@nongnu.org Date: Thu, 3 Sep 2009 02:32:13 +0200 Message-Id: <1251937933-16778-1-git-send-email-jcd@tribudubois.net> X-Mailer: git-send-email 1.6.0.4 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: Jean-Christophe DUBOIS Subject: [Qemu-devel] [PATCH] Fix error checking and cleaning in path.c X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Very little error checking was done in path.c and we were leaking some memories in case of error. Signed-off-by: Jean-Christophe Dubois --- path.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 64 insertions(+), 12 deletions(-) diff --git a/path.c b/path.c index cc9e007..24e8fdd 100644 --- a/path.c +++ b/path.c @@ -40,15 +40,50 @@ static int strneq(const char *s1, unsigned int n, const char *s2) static struct pathelem *add_entry(struct pathelem *root, const char *name); +static void free_entry(struct pathelem *ptr) +{ + if(ptr) + { + while(ptr->num_entries) { + if (ptr->entries[ptr->num_entries -1]) { + free_entry(ptr->entries[ptr->num_entries -1]); + qemu_free(ptr->entries[ptr->num_entries -1]); + ptr->entries[ptr->num_entries -1] = NULL; + } + ptr->num_entries--; + } + + if (ptr->name) { + qemu_free(ptr->name); + ptr->name = NULL; + } + + if (ptr->pathname) { + free(ptr->pathname); + ptr->pathname = NULL; + } + } +} + static struct pathelem *new_entry(const char *root, struct pathelem *parent, const char *name) { - struct pathelem *new = malloc(sizeof(*new)); - new->name = strdup(name); - asprintf(&new->pathname, "%s/%s", root, name); - new->num_entries = 0; + struct pathelem *new = qemu_mallocz(sizeof(*new)); + + if (new) { + if (!(new->name = qemu_strdup(name))) + goto fail; + if (asprintf(&new->pathname, "%s/%s", root, name) < 0) + goto fail; + new->num_entries = 0; + } return new; + +fail: + free_entry(new); + qemu_free(new); + return NULL; } #define streq(a,b) (strcmp((a), (b)) == 0) @@ -57,7 +92,7 @@ static struct pathelem *add_dir_maybe(struct pathelem *path) { DIR *dir; - if ((dir = opendir(path->pathname)) != NULL) { + if (path && ((dir = opendir(path->pathname)) != NULL)) { struct dirent *dirent; while ((dirent = readdir(dir)) != NULL) { @@ -67,6 +102,7 @@ static struct pathelem *add_dir_maybe(struct pathelem *path) } closedir(dir); } + return path; } @@ -74,13 +110,25 @@ static struct pathelem *add_entry(struct pathelem *root, const char *name) { root->num_entries++; - root = realloc(root, sizeof(*root) + root = qemu_realloc(root, sizeof(*root) + sizeof(root->entries[0])*root->num_entries); - root->entries[root->num_entries-1] = new_entry(root->pathname, root, name); - root->entries[root->num_entries-1] - = add_dir_maybe(root->entries[root->num_entries-1]); + if (root) { + root->entries[root->num_entries-1] + = add_dir_maybe(new_entry(root->pathname, root, name)); + + if (!root->entries[root->num_entries-1]) + goto fail; + } else { + /* if realloc failed, we have leaked some memory and we can't recover it */ + } + return root; + +fail: + free_entry(root); + qemu_free(root); + return NULL; } /* This needs to be done after tree is stabilized (ie. no more reallocs!). */ @@ -140,10 +188,14 @@ void init_paths(const char *prefix) } else pstrcpy(pref_buf, sizeof(pref_buf), prefix + 1); - base = new_entry("", NULL, pref_buf); - base = add_dir_maybe(base); + base = add_dir_maybe(new_entry("", NULL, pref_buf)); + + if (!base) + abort(); + if (base->num_entries == 0) { - free (base); + free_entry(base); + qemu_free (base); base = NULL; } else { set_parents(base, base);