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

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
Loading
Loading
Loading
Loading
+50 −51
Original line number Diff line number Diff line
@@ -1928,7 +1928,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
{
	struct smb_rqst rqst;
	struct smb2_create_req *req;
	struct smb2_create_rsp *rsp;
	struct smb2_create_rsp *rsp = NULL;
	struct TCP_Server_Info *server;
	struct cifs_ses *ses = tcon->ses;
	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,
	char *pc_buf = NULL;
	int flags = 0;
	unsigned int total_len;
	__le16 *path = cifs_convert_path_to_utf16(full_path, cifs_sb);

	if (!path)
		return -ENOMEM;
	__le16 *utf16_path = NULL;

	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))
		server = ses->server;
	else
		return -EIO;
	else {
		rc = -EIO;
		goto err_free_path;
	}

	/* resource #2: request */
	rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len);

	if (rc)
		return rc;
		goto err_free_path;


	if (smb3_encryption_required(tcon))
		flags |= CIFS_TRANSFORM_REQ;


	req->ImpersonationLevel = IL_IMPERSONATION;
	req->DesiredAccess = cpu_to_le32(FILE_WRITE_ATTRIBUTES);
	/* File attributes ignored on open (used in create though) */
@@ -1992,50 +1996,44 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
		req->sync_hdr.Flags |= SMB2_FLAGS_DFS_OPERATIONS;
		rc = alloc_path_with_tree_prefix(&copy_path, &copy_size,
						 &name_len,
						 tcon->treeName, path);
		if (rc) {
			cifs_small_buf_release(req);
			return rc;
		}
						 tcon->treeName, utf16_path);
		if (rc)
			goto err_free_req;

		req->NameLength = cpu_to_le16(name_len * 2);
		uni_path_len = copy_size;
		path = copy_path;
		/* free before overwriting resource */
		kfree(utf16_path);
		utf16_path = copy_path;
	} 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 */
		req->NameLength = cpu_to_le16(uni_path_len - 2);
		if (uni_path_len % 8 != 0) {
			copy_size = roundup(uni_path_len, 8);
			copy_path = kzalloc(copy_size, GFP_KERNEL);
			if (!copy_path) {
				cifs_small_buf_release(req);
				return -ENOMEM;
				rc = -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 = 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_base = path;
	iov[1].iov_base = utf16_path;
	req->RequestedOplockLevel = SMB2_OPLOCK_LEVEL_NONE;

	if (tcon->posix_extensions) {
		if (n_iov > 2) {
			struct create_context *ccontext =
			    (struct create_context *)iov[n_iov-1].iov_base;
			ccontext->Next =
				cpu_to_le32(iov[n_iov-1].iov_len);
		}

		/* resource #3: posix buf */
		rc = add_posix_context(iov, &n_iov, mode);
		if (rc) {
			cifs_small_buf_release(req);
			kfree(copy_path);
			return rc;
		}
		if (rc)
			goto err_free_req;
		pc_buf = iov[n_iov-1].iov_base;
	}

@@ -2044,18 +2042,17 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
	rqst.rq_iov = iov;
	rqst.rq_nvec = n_iov;

	rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags,
			    &rsp_iov);

	cifs_small_buf_release(req);
	rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;

	if (rc != 0) {
	/* resource #4: response buffer */
	rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov);
	if (rc) {
		cifs_stats_fail_inc(tcon, SMB2_CREATE_HE);
		trace_smb3_posix_mkdir_err(xid, tcon->tid, ses->Suid,
				    CREATE_NOT_FILE, FILE_WRITE_ATTRIBUTES, rc);
		goto smb311_mkdir_exit;
	} else
					   CREATE_NOT_FILE,
					   FILE_WRITE_ATTRIBUTES, rc);
		goto err_free_rsp_buf;
	}

	rsp = (struct smb2_create_rsp *)rsp_iov.iov_base;
	trace_smb3_posix_mkdir_done(xid, rsp->PersistentFileId, tcon->tid,
				    ses->Suid, CREATE_NOT_FILE,
				    FILE_WRITE_ATTRIBUTES);
@@ -2064,12 +2061,14 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,

	/* Eventually save off posix specific response info and timestaps */

smb311_mkdir_exit:
	kfree(copy_path);
	kfree(pc_buf);
err_free_rsp_buf:
	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;

}
#endif /* SMB311 */