Skip to content

Commit

Permalink
cifs: return ENAMETOOLONG for overlong names in cifs_open()/cifs_look…
Browse files Browse the repository at this point in the history
…up()

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>
Cc: <stable@vger.kernel.org>
  • Loading branch information
Ronnie Sahlberg authored and Steve French committed Aug 23, 2017
1 parent 42bec21 commit d3edede
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions fs/cifs/dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,20 @@ build_path_from_dentry_optional_prefix(struct dentry *direntry, bool prefix)
}

/*
* Don't allow path components longer than the server max.
* Don't allow the separator character in a path component.
* The VFS will not allow "/", but "\" is allowed by posix.
*/
static int
check_name(struct dentry *direntry)
check_name(struct dentry *direntry, struct cifs_tcon *tcon)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
int i;

if (unlikely(direntry->d_name.len >
tcon->fsAttrInfo.MaxPathNameComponentLength))
return -ENAMETOOLONG;

if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
for (i = 0; i < direntry->d_name.len; i++) {
if (direntry->d_name.name[i] == '\\') {
Expand Down Expand Up @@ -500,10 +505,6 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
return finish_no_open(file, res);
}

rc = check_name(direntry);
if (rc)
return rc;

xid = get_xid();

cifs_dbg(FYI, "parent inode = 0x%p name is: %pd and dentry = 0x%p\n",
Expand All @@ -516,6 +517,11 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
}

tcon = tlink_tcon(tlink);

rc = check_name(direntry, tcon);
if (rc)
goto out_free_xid;

server = tcon->ses->server;

if (server->ops->new_lease_key)
Expand Down Expand Up @@ -776,7 +782,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
}
pTcon = tlink_tcon(tlink);

rc = check_name(direntry);
rc = check_name(direntry, pTcon);
if (rc)
goto lookup_out;

Expand Down

0 comments on commit d3edede

Please sign in to comment.