Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 430

kernel-2.6.18-238.el5.src.rpm

From: Jeff Layton <jlayton@redhat.com>
Date: Mon, 16 Nov 2009 14:22:51 -0500
Subject: [cifs] add loop check when mounting dfs tree
Message-id: <1258381372-19132-6-git-send-email-jlayton@redhat.com>
Patchwork-id: 21381
O-Subject: [RHEL5.5 PATCH 5/6] BZ#513410: cifs: Added loop check when mounting
	DFS tree.
Bugzilla: 513410
RH-Acked-by: Peter Staubach <staubach@redhat.com>

From: Igor Mammedov <niallain@gmail.com>

Added loop check when mounting DFS tree. mount will fail with
ELOOP if referral walks exceed MAX_NESTED_LINK count.

Signed-off-by: Igor Mammedov <niallain@gmail.com>
Acked-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
Signed-off-by: Jeff Layton <jlayton@redhat.com>

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index fe8946f..3302e57 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -29,14 +29,10 @@
 #include <linux/delay.h>
 #include <linux/completion.h>
 #include <linux/version.h>
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0)
 #include <linux/mempool.h>
-#include <linux/pagevec.h>
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,19)
-#include <linux/freezer.h>
-#endif /* 2.6.19 */
-#endif
 #include <linux/kthread.h>
+#include <linux/pagevec.h>
+#include <linux/namei.h>
 #include <asm/uaccess.h>
 #include <asm/processor.h>
 #include <net/ipv6.h>
@@ -2348,6 +2344,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
 #ifdef CONFIG_CIFS_DFS_UPCALL
 	struct dfs_info3_param *referrals = NULL;
 	unsigned int num_referrals = 0;
+	int referral_walks_count = 0;
 try_mount_again:
 #endif
 	full_path = NULL;
@@ -2596,6 +2593,16 @@ remote_path_check:
 	/* get referral if needed */
 	if (rc == -EREMOTE) {
 #ifdef CONFIG_CIFS_DFS_UPCALL
+		if (referral_walks_count > MAX_NESTED_LINKS) {
+			/*
+			 * BB: when we implement proper loop detection,
+			 *     we will remove this check. But now we need it
+			 *     to prevent an indefinite loop if 'DFS tree' is
+			 *     misconfigured (i.e. has loops).
+			 */
+			rc = -ELOOP;
+			goto mount_fail_check;
+		}
 		/* convert forward to back slashes in prepath here if needed */
 		if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
 			convert_delimiter(cifs_sb->prepath,
@@ -2629,6 +2636,7 @@ remote_path_check:
 			cleanup_volume_info(&volume_info);
 			FreeXid(xid);
 			kfree(full_path);
+			referral_walks_count++;
 			goto try_mount_again;
 		}
 #else /* No DFS support, return error on mount */