Commit 256b4c3f authored by Aurelien Aptel's avatar Aurelien Aptel Committed by Steve French

CIFS: fix memory leak and remove dead code

also fixes error code in smb311_posix_mkdir() (where
the error assignment needs to go before the goto)
a typo that Dan Carpenter and Paulo and Gustavo
pointed out.
Signed-off-by: default avatarAurelien Aptel <aaptel@suse.com>
Signed-off-by: default avatarDan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: default avatarGustavo A. R. Silva <gustavo@embeddedor.com>
Reviewed-by: default avatarPaulo Alcantara <palcantara@suse.de>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 7420451f
...@@ -1928,7 +1928,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, ...@@ -1928,7 +1928,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
{ {
struct smb_rqst rqst; struct smb_rqst rqst;
struct smb2_create_req *req; struct smb2_create_req *req;
struct smb2_create_rsp *rsp; struct smb2_create_rsp *rsp = NULL;
struct TCP_Server_Info *server; struct TCP_Server_Info *server;
struct cifs_ses *ses = tcon->ses; struct cifs_ses *ses = tcon->ses;
struct kvec iov[3]; /* make sure at least one for each open context */ struct kvec iov[3]; /* make sure at least one for each open context */
...@@ -1943,27 +1943,31 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, ...@@ -1943,27 +1943,31 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
char *pc_buf = NULL; char *pc_buf = NULL;
int flags = 0; int flags = 0;
unsigned int total_len; unsigned int total_len;
__le16 *path = cifs_convert_path_to_utf16(full_path, cifs_sb); __le16 *utf16_path = NULL;
if (!path)
return -ENOMEM;
cifs_dbg(FYI, "mkdir\n"); cifs_dbg(FYI, "mkdir\n");
/* resource #1: path allocation */
utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
if (!utf16_path)
return -ENOMEM;
if (ses && (ses->server)) if (ses && (ses->server))
server = ses->server; server = ses->server;
else else {
return -EIO; rc = -EIO;
goto err_free_path;
}
/* resource #2: request */
rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len); rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len);
if (rc) if (rc)
return rc; goto err_free_path;
if (smb3_encryption_required(tcon)) if (smb3_encryption_required(tcon))
flags |= CIFS_TRANSFORM_REQ; flags |= CIFS_TRANSFORM_REQ;
req->ImpersonationLevel = IL_IMPERSONATION; req->ImpersonationLevel = IL_IMPERSONATION;
req->DesiredAccess = cpu_to_le32(FILE_WRITE_ATTRIBUTES); req->DesiredAccess = cpu_to_le32(FILE_WRITE_ATTRIBUTES);
/* File attributes ignored on open (used in create though) */ /* File attributes ignored on open (used in create though) */
...@@ -1992,50 +1996,44 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, ...@@ -1992,50 +1996,44 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
req->sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS; req->sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
rc = alloc_path_with_tree_prefix(&copy_path, &copy_size, rc = alloc_path_with_tree_prefix(&copy_path, &copy_size,
&name_len, &name_len,
tcon->treeName, path); tcon->treeName, utf16_path);
if (rc) { if (rc)
cifs_small_buf_release(req); goto err_free_req;
return rc;
}
req->NameLength = cpu_to_le16(name_len * 2); req->NameLength = cpu_to_le16(name_len * 2);
uni_path_len = copy_size; uni_path_len = copy_size;
path = copy_path; /* free before overwriting resource */
kfree(utf16_path);
utf16_path = copy_path;
} else { } else {
uni_path_len = (2 * UniStrnlen((wchar_t *)path, PATH_MAX)) + 2; uni_path_len = (2 * UniStrnlen((wchar_t *)utf16_path, PATH_MAX)) + 2;
/* MUST set path len (NameLength) to 0 opening root of share */ /* MUST set path len (NameLength) to 0 opening root of share */
req->NameLength = cpu_to_le16(uni_path_len - 2); req->NameLength = cpu_to_le16(uni_path_len - 2);
if (uni_path_len % 8 != 0) { if (uni_path_len % 8 != 0) {
copy_size = roundup(uni_path_len, 8); copy_size = roundup(uni_path_len, 8);
copy_path = kzalloc(copy_size, GFP_KERNEL); copy_path = kzalloc(copy_size, GFP_KERNEL);
if (!copy_path) { if (!copy_path) {
cifs_small_buf_release(req); rc = -ENOMEM;
return -ENOMEM; goto err_free_req;
} }
memcpy((char *)copy_path, (const char *)path, memcpy((char *)copy_path, (const char *)utf16_path,
uni_path_len); uni_path_len);
uni_path_len = copy_size; uni_path_len = copy_size;
path = copy_path; /* free before overwriting resource */
kfree(utf16_path);
utf16_path = copy_path;
} }
} }
iov[1].iov_len = uni_path_len; iov[1].iov_len = uni_path_len;
iov[1].iov_base = path; iov[1].iov_base = utf16_path;
req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_NONE; req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_NONE;
if (tcon->posix_extensions) { if (tcon->posix_extensions) {
if (n_iov > 2) { /* resource #3: posix buf */
struct create_context *ccontext =
(struct create_context *)iov[n_iov-1].iov_base;
ccontext->Next =
cpu_to_le32(iov[n_iov-1].iov_len);
}
rc = add_posix_context(iov, &n_iov, mode); rc = add_posix_context(iov, &n_iov, mode);
if (rc) { if (rc)
cifs_small_buf_release(req); goto err_free_req;
kfree(copy_path);
return rc;
}
pc_buf = iov[n_iov-1].iov_base; pc_buf = iov[n_iov-1].iov_base;
} }
...@@ -2044,18 +2042,17 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, ...@@ -2044,18 +2042,17 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
rqst.rq_iov = iov; rqst.rq_iov = iov;
rqst.rq_nvec = n_iov; rqst.rq_nvec = n_iov;
rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, /* resource #4: response buffer */
&rsp_iov); rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
if (rc) {
cifs_small_buf_release(req);
rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
if (rc != 0) {
cifs_stats_fail_inc(tcon, SMB2_CREATE_HE); cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
trace_smb3_posix_mkdir_err(xid, tcon->tid, ses->Suid, trace_smb3_posix_mkdir_err(xid, tcon->tid, ses->Suid,
CREATE_NOT_FILE, FILE_WRITE_ATTRIBUTES, rc); CREATE_NOT_FILE,
goto smb311_mkdir_exit; FILE_WRITE_ATTRIBUTES, rc);
} else goto err_free_rsp_buf;
}
rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
trace_smb3_posix_mkdir_done(xid, rsp->PersistentFileId, tcon->tid, trace_smb3_posix_mkdir_done(xid, rsp->PersistentFileId, tcon->tid,
ses->Suid, CREATE_NOT_FILE, ses->Suid, CREATE_NOT_FILE,
FILE_WRITE_ATTRIBUTES); FILE_WRITE_ATTRIBUTES);
...@@ -2064,12 +2061,14 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode, ...@@ -2064,12 +2061,14 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
/* Eventually save off posix specific response info and timestaps */ /* Eventually save off posix specific response info and timestaps */
smb311_mkdir_exit: err_free_rsp_buf:
kfree(copy_path);
kfree(pc_buf);
free_rsp_buf(resp_buftype, rsp); free_rsp_buf(resp_buftype, rsp);
kfree(pc_buf);
err_free_req:
cifs_small_buf_release(req);
err_free_path:
kfree(utf16_path);
return rc; return rc;
} }
#endif /* SMB311 */ #endif /* SMB311 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment