diff options
| -rw-r--r-- | fs/cifs/dir.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 56366e984076..569d3fb736be 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -194,15 +194,20 @@ cifs_bp_rename_retry: | |||
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | /* | 196 | /* |
| 197 | * Don't allow path components longer than the server max. | ||
| 197 | * Don't allow the separator character in a path component. | 198 | * Don't allow the separator character in a path component. |
| 198 | * The VFS will not allow "/", but "\" is allowed by posix. | 199 | * The VFS will not allow "/", but "\" is allowed by posix. |
| 199 | */ | 200 | */ |
| 200 | static int | 201 | static int |
| 201 | check_name(struct dentry *direntry) | 202 | check_name(struct dentry *direntry, struct cifs_tcon *tcon) |
| 202 | { | 203 | { |
| 203 | struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); | 204 | struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); |
| 204 | int i; | 205 | int i; |
| 205 | 206 | ||
| 207 | if (unlikely(direntry->d_name.len > | ||
| 208 | tcon->fsAttrInfo.MaxPathNameComponentLength)) | ||
| 209 | return -ENAMETOOLONG; | ||
| 210 | |||
| 206 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { | 211 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { |
| 207 | for (i = 0; i < direntry->d_name.len; i++) { | 212 | for (i = 0; i < direntry->d_name.len; i++) { |
| 208 | if (direntry->d_name.name[i] == '\\') { | 213 | if (direntry->d_name.name[i] == '\\') { |
| @@ -500,10 +505,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
| 500 | return finish_no_open(file, res); | 505 | return finish_no_open(file, res); |
| 501 | } | 506 | } |
| 502 | 507 | ||
| 503 | rc = check_name(direntry); | ||
| 504 | if (rc) | ||
| 505 | return rc; | ||
| 506 | |||
| 507 | xid = get_xid(); | 508 | xid = get_xid(); |
| 508 | 509 | ||
| 509 | cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", | 510 | cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n", |
| @@ -516,6 +517,11 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
| 516 | } | 517 | } |
| 517 | 518 | ||
| 518 | tcon = tlink_tcon(tlink); | 519 | tcon = tlink_tcon(tlink); |
| 520 | |||
| 521 | rc = check_name(direntry, tcon); | ||
| 522 | if (rc) | ||
| 523 | goto out_free_xid; | ||
| 524 | |||
| 519 | server = tcon->ses->server; | 525 | server = tcon->ses->server; |
| 520 | 526 | ||
| 521 | if (server->ops->new_lease_key) | 527 | if (server->ops->new_lease_key) |
| @@ -776,7 +782,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
| 776 | } | 782 | } |
| 777 | pTcon = tlink_tcon(tlink); | 783 | pTcon = tlink_tcon(tlink); |
| 778 | 784 | ||
| 779 | rc = check_name(direntry); | 785 | rc = check_name(direntry, pTcon); |
| 780 | if (rc) | 786 | if (rc) |
| 781 | goto lookup_out; | 787 | goto lookup_out; |
| 782 | 788 | ||
