From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LOw5K-0007CM-2Z for qemu-devel@nongnu.org; Mon, 19 Jan 2009 10:30:42 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LOw5J-0007C2-De for qemu-devel@nongnu.org; Mon, 19 Jan 2009 10:30:41 -0500 Received: from [199.232.76.173] (port=54941 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LOw5J-0007Bv-5f for qemu-devel@nongnu.org; Mon, 19 Jan 2009 10:30:41 -0500 Received: from [84.20.150.76] (port=44568 helo=narury.org) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LOw5I-0006c4-LX for qemu-devel@nongnu.org; Mon, 19 Jan 2009 10:30:40 -0500 Received: from kos.to (localhost.localdomain [127.0.0.1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by narury.org (Postfix) with ESMTP id 86CB43274002 for ; Mon, 19 Jan 2009 17:30:33 +0200 (EET) Date: Mon, 19 Jan 2009 17:30:33 +0200 From: Riku Voipio Message-ID: <20090119153033.GA21176@kos.to> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Subject: [Qemu-devel] [PATCH] linux-user: break recursion loop on symlink to . or .. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org From: Mika Westerberg This patch corrects bug in qemu where it contructs its internal paths and ends up in recursion loop when filesystem contains symlink that points to dot '.'. (Riku: some whitespace fudging to minize diff - the whole file needs reindenting...) Signed-off-by: Riku Voipio --- linux-user/path.c | 37 ++++++++++++++++++++++++++++++++++++- 1 files changed, 36 insertions(+), 1 deletions(-) diff --git a/linux-user/path.c b/linux-user/path.c index 06b1f5f..b991af0 100644 --- a/linux-user/path.c +++ b/linux-user/path.c @@ -4,6 +4,7 @@ The assumption is that this area does not change. */ #include +#include #include #include #include @@ -52,6 +53,38 @@ static struct pathelem *new_entry(const char *root, #define streq(a,b) (strcmp((a), (b)) == 0) +/* + * Checks whether directory entry (dent) is valid. This + * means that symlinks pointing to '.' and '..' should + * be skipped by main recursion code. Returns 1 when + * entry is valid. + */ +static int +is_dentry_valid(const char *path, const struct dirent *dent) +{ + char fullpath[PATH_MAX]; + char linkbuf[PATH_MAX]; + ssize_t len; + + assert(path != NULL); + assert(dent != NULL); + + if (dent->d_type != DT_LNK) + return (1); + + (void) snprintf(fullpath, sizeof (fullpath), "%s/%s", + path, dent->d_name); + + if ((len = readlink(fullpath, linkbuf, sizeof (linkbuf) - 1)) != -1) { + linkbuf[len] = '\0'; + if (streq(linkbuf, ".") || streq(linkbuf, "..")) + return (0); + } + + return (1); +} + +/* TODO: add recursion count check */ static struct pathelem *add_dir_maybe(struct pathelem *path) { DIR *dir; @@ -61,7 +94,9 @@ static struct pathelem *add_dir_maybe(struct pathelem *path) while ((dirent = readdir(dir)) != NULL) { if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){ - path = add_entry(path, dirent->d_name); + if (is_dentry_valid(path->pathname, dirent)) { + path = add_entry(path, dirent->d_name); + } } } closedir(dir); -- 1.5.6.5 -- "rm -rf" only sounds scary if you don't have backups