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 */