cifs: fixes for get_inode_info
[ Upstream commit fc20c523211a38b87fc850a959cb2149e4fd64b0 ] Fix potential memory leaks, add error checking, remove unnecessary initialisation of status_file_deleted and do not use cifs_iget() to get inode in reparse_info_to_fattr since fattrs may not be fully set. Fixes: ffceb7640cbf ("smb: client: do not defer close open handles to deleted files") Reported-by: Paulo Alcantara <pc@manguebit.com> Signed-off-by: Meetakshi Setiya <msetiya@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
91cdeb0d4b
commit
1598a015c7
@ -501,7 +501,6 @@ struct cifsFileInfo *cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
|
||||
cfile->uid = current_fsuid();
|
||||
cfile->dentry = dget(dentry);
|
||||
cfile->f_flags = file->f_flags;
|
||||
cfile->status_file_deleted = false;
|
||||
cfile->invalidHandle = false;
|
||||
cfile->deferred_close_scheduled = false;
|
||||
cfile->tlink = cifs_get_tlink(tlink);
|
||||
|
@ -820,8 +820,10 @@ cifs_get_file_info(struct file *filp)
|
||||
void *page = alloc_dentry_path();
|
||||
const unsigned char *path;
|
||||
|
||||
if (!server->ops->query_file_info)
|
||||
if (!server->ops->query_file_info) {
|
||||
free_dentry_path(page);
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
xid = get_xid();
|
||||
rc = server->ops->query_file_info(xid, tcon, cfile, &data);
|
||||
@ -835,8 +837,8 @@ cifs_get_file_info(struct file *filp)
|
||||
}
|
||||
path = build_path_from_dentry(dentry, page);
|
||||
if (IS_ERR(path)) {
|
||||
free_dentry_path(page);
|
||||
return PTR_ERR(path);
|
||||
rc = PTR_ERR(path);
|
||||
goto cgfi_exit;
|
||||
}
|
||||
cifs_open_info_to_fattr(&fattr, &data, inode->i_sb);
|
||||
if (fattr.cf_flags & CIFS_FATTR_DELETE_PENDING)
|
||||
@ -1009,7 +1011,6 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
|
||||
struct kvec rsp_iov, *iov = NULL;
|
||||
int rsp_buftype = CIFS_NO_BUFFER;
|
||||
u32 tag = data->reparse.tag;
|
||||
struct inode *inode = NULL;
|
||||
int rc = 0;
|
||||
|
||||
if (!tag && server->ops->query_reparse_point) {
|
||||
@ -1049,12 +1050,8 @@ static int reparse_info_to_fattr(struct cifs_open_info_data *data,
|
||||
|
||||
if (tcon->posix_extensions)
|
||||
smb311_posix_info_to_fattr(fattr, data, sb);
|
||||
else {
|
||||
else
|
||||
cifs_open_info_to_fattr(fattr, data, sb);
|
||||
inode = cifs_iget(sb, fattr);
|
||||
if (inode && fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)
|
||||
cifs_mark_open_handles_for_deleted_file(inode, full_path);
|
||||
}
|
||||
out:
|
||||
fattr->cf_cifstag = data->reparse.tag;
|
||||
free_rsp_buf(rsp_buftype, rsp_iov.iov_base);
|
||||
@ -1109,9 +1106,9 @@ static int cifs_get_fattr(struct cifs_open_info_data *data,
|
||||
full_path, fattr);
|
||||
} else {
|
||||
cifs_open_info_to_fattr(fattr, data, sb);
|
||||
if (fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)
|
||||
cifs_mark_open_handles_for_deleted_file(*inode, full_path);
|
||||
}
|
||||
if (!rc && fattr->cf_flags & CIFS_FATTR_DELETE_PENDING)
|
||||
cifs_mark_open_handles_for_deleted_file(*inode, full_path);
|
||||
break;
|
||||
case -EREMOTE:
|
||||
/* DFS link, no metadata available on this server */
|
||||
@ -1340,6 +1337,8 @@ int smb311_posix_get_inode_info(struct inode **inode,
|
||||
goto out;
|
||||
|
||||
rc = update_inode_info(sb, &fattr, inode);
|
||||
if (!rc && fattr.cf_flags & CIFS_FATTR_DELETE_PENDING)
|
||||
cifs_mark_open_handles_for_deleted_file(*inode, full_path);
|
||||
out:
|
||||
kfree(fattr.cf_symlink_target);
|
||||
return rc;
|
||||
@ -1503,6 +1502,9 @@ iget_root:
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!rc && fattr.cf_flags & CIFS_FATTR_DELETE_PENDING)
|
||||
cifs_mark_open_handles_for_deleted_file(inode, path);
|
||||
|
||||
if (rc && tcon->pipe) {
|
||||
cifs_dbg(FYI, "ipc connection - fake read inode\n");
|
||||
spin_lock(&inode->i_lock);
|
||||
|
Loading…
x
Reference in New Issue
Block a user