diff options
author | Igor Mammedov <niallain@gmail.com> | 2009-04-21 11:31:05 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2009-04-30 13:24:09 -0400 |
commit | 5c2503a8e339fbc82f49d5706c5a4ad650dd9711 (patch) | |
tree | 3b56e1e41b35ef743cc469b91f0aff184ec06898 /fs/cifs | |
parent | 1af28ceb923d04357733642a3dbc4497da4db1c2 (diff) |
Added loop check when mounting DFS tree.
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>
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/connect.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 579a628d1e65..7e5d4fda4936 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/kthread.h> | 32 | #include <linux/kthread.h> |
33 | #include <linux/pagevec.h> | 33 | #include <linux/pagevec.h> |
34 | #include <linux/freezer.h> | 34 | #include <linux/freezer.h> |
35 | #include <linux/namei.h> | ||
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
36 | #include <asm/processor.h> | 37 | #include <asm/processor.h> |
37 | #include <net/ipv6.h> | 38 | #include <net/ipv6.h> |
@@ -2278,6 +2279,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2278 | #ifdef CONFIG_CIFS_DFS_UPCALL | 2279 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2279 | struct dfs_info3_param *referrals = NULL; | 2280 | struct dfs_info3_param *referrals = NULL; |
2280 | unsigned int num_referrals = 0; | 2281 | unsigned int num_referrals = 0; |
2282 | int referral_walks_count = 0; | ||
2281 | try_mount_again: | 2283 | try_mount_again: |
2282 | #endif | 2284 | #endif |
2283 | full_path = NULL; | 2285 | full_path = NULL; |
@@ -2525,6 +2527,16 @@ remote_path_check: | |||
2525 | /* get referral if needed */ | 2527 | /* get referral if needed */ |
2526 | if (rc == -EREMOTE) { | 2528 | if (rc == -EREMOTE) { |
2527 | #ifdef CONFIG_CIFS_DFS_UPCALL | 2529 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2530 | if (referral_walks_count > MAX_NESTED_LINKS) { | ||
2531 | /* | ||
2532 | * BB: when we implement proper loop detection, | ||
2533 | * we will remove this check. But now we need it | ||
2534 | * to prevent an indefinite loop if 'DFS tree' is | ||
2535 | * misconfigured (i.e. has loops). | ||
2536 | */ | ||
2537 | rc = -ELOOP; | ||
2538 | goto mount_fail_check; | ||
2539 | } | ||
2528 | /* convert forward to back slashes in prepath here if needed */ | 2540 | /* convert forward to back slashes in prepath here if needed */ |
2529 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) | 2541 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0) |
2530 | convert_delimiter(cifs_sb->prepath, | 2542 | convert_delimiter(cifs_sb->prepath, |
@@ -2558,6 +2570,7 @@ remote_path_check: | |||
2558 | cleanup_volume_info(&volume_info); | 2570 | cleanup_volume_info(&volume_info); |
2559 | FreeXid(xid); | 2571 | FreeXid(xid); |
2560 | kfree(full_path); | 2572 | kfree(full_path); |
2573 | referral_walks_count++; | ||
2561 | goto try_mount_again; | 2574 | goto try_mount_again; |
2562 | } | 2575 | } |
2563 | #else /* No DFS support, return error on mount */ | 2576 | #else /* No DFS support, return error on mount */ |