Commit 30ce55b1 authored by Su Hui's avatar Su Hui Committed by Yifan Qiao
Browse files

smb: client: fix possible double free in smb2_set_ea()

stable inclusion
from stable-v6.6.32
commit b1813c220b76f60b1727984794377c4aa849d4c1
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB2SWG
CVE: CVE-2024-50152

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=b1813c220b76f60b1727984794377c4aa849d4c1



--------------------------------

[ Upstream commit 19ebc1e6cab334a8193398d4152deb76019b5d34 ]

Clang static checker(scan-build) warning:
fs/smb/client/smb2ops.c:1304:2: Attempt to free released memory.
 1304 |         kfree(ea);
      |         ^~~~~~~~~

There is a double free in such case:
'ea is initialized to NULL' -> 'first successful memory allocation for
ea' -> 'something failed, goto sea_exit' -> 'first memory release for ea'
-> 'goto replay_again' -> 'second goto sea_exit before allocate memory
for ea' -> 'second memory release for ea resulted in double free'.

Re-initialie 'ea' to NULL near to the replay_again label, it can fix this
double free problem.

Fixes: 4f1fffa23769 ("cifs: commands that are retried should have replay flag set")
Reviewed-by: default avatarDan Carpenter <dan.carpenter@linaro.org>
Signed-off-by: default avatarSu Hui <suhui@nfschina.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarYifan Qiao <qiaoyifan4@huawei.com>
parent 2e089ebd
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -1122,7 +1122,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
	struct cifs_fid fid;
	unsigned int size[1];
	void *data[1];
	struct smb2_file_full_ea_info *ea = NULL;
	struct smb2_file_full_ea_info *ea;
	struct smb2_query_info_rsp *rsp;
	int rc, used_len = 0;
	int retries = 0, cur_sleep = 1;
@@ -1143,6 +1143,7 @@ smb2_set_ea(const unsigned int xid, struct cifs_tcon *tcon,
	if (!utf16_path)
		return -ENOMEM;

	ea = NULL;
	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
	vars = kzalloc(sizeof(*vars), GFP_KERNEL);
	if (!vars) {