Skip to content

Commit e606696

Browse files
Ronnie Sahlberggregkh
authored andcommitted
cifs: return ENAMETOOLONG for overlong names in cifs_open()/cifs_lookup()
commit d3edede29f74d335f81d95a4588f5f136a9f7dcf upstream. Add checking for the path component length and verify it is <= the maximum that the server advertizes via FileFsAttributeInformation. With this patch cifs.ko will now return ENAMETOOLONG instead of ENOENT when users to access an overlong path. To test this, try to cd into a (non-existing) directory on a CIFS share that has a too long name: cd /mnt/aaaaaaaaaaaaaaa... and it now should show a good error message from the shell: bash: cd: /mnt/aaaaaaaaaaaaaaaa...aaaaaa: File name too long rh bz 1153996 Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 210b41b commit e606696

1 file changed

Lines changed: 12 additions & 6 deletions

File tree

fs/cifs/dir.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,15 +183,20 @@ build_path_from_dentry(struct dentry *direntry)
183183
}
184184

185185
/*
186+
* Don't allow path components longer than the server max.
186187
* Don't allow the separator character in a path component.
187188
* The VFS will not allow "/", but "\" is allowed by posix.
188189
*/
189190
static int
190-
check_name(struct dentry *direntry)
191+
check_name(struct dentry *direntry, struct cifs_tcon *tcon)
191192
{
192193
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
193194
int i;
194195

196+
if (unlikely(direntry->d_name.len >
197+
tcon->fsAttrInfo.MaxPathNameComponentLength))
198+
return -ENAMETOOLONG;
199+
195200
if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
196201
for (i = 0; i < direntry->d_name.len; i++) {
197202
if (direntry->d_name.name[i] == '\\') {
@@ -489,10 +494,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
489494
return finish_no_open(file, res);
490495
}
491496

492-
rc = check_name(direntry);
493-
if (rc)
494-
return rc;
495-
496497
xid = get_xid();
497498

498499
cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
@@ -505,6 +506,11 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
505506
}
506507

507508
tcon = tlink_tcon(tlink);
509+
510+
rc = check_name(direntry, tcon);
511+
if (rc)
512+
goto out_free_xid;
513+
508514
server = tcon->ses->server;
509515

510516
if (server->ops->new_lease_key)
@@ -765,7 +771,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
765771
}
766772
pTcon = tlink_tcon(tlink);
767773

768-
rc = check_name(direntry);
774+
rc = check_name(direntry, pTcon);
769775
if (rc)
770776
goto lookup_out;
771777

0 commit comments

Comments
 (0)