diff options
author | Meetakshi Setiya <msetiya@microsoft.com> | 2024-03-14 08:05:49 -0400 |
---|---|---|
committer | Steve French <stfrench@microsoft.com> | 2024-03-14 13:54:27 -0500 |
commit | fc20c523211a38b87fc850a959cb2149e4fd64b0 (patch) | |
tree | d6a5d9294fa584471fb0368933985e28deb2142a /fs/smb | |
parent | f1b8224b4e6ed59e7e6f5c548673c67410098d8d (diff) |
cifs: fixes for get_inode_info
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>
Diffstat (limited to 'fs/smb')
-rw-r--r-- | fs/smb/client/file.c | 1 | ||||
-rw-r--r-- | fs/smb/client/inode.c | 24 |
2 files changed, 13 insertions, 12 deletions
diff --git a/fs/smb/client/file.c b/fs/smb/client/file.c index e7d5e8f972a0..16aadce492b2 100644 --- a/fs/smb/client/file.c +++ b/fs/smb/client/file.c @@ -486,7 +486,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); diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c index 8177ec59afee..6092729bf7f6 100644 --- a/fs/smb/client/inode.c +++ b/fs/smb/client/inode.c @@ -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; @@ -1501,6 +1500,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); |