Skip to contentSkip to conversation

unreachable code and memory leaks

smb3 Gustavo A. R. Silva 2 participants 5 messages Jun 18, 2018 – Jun 19, 2018

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hi Steve,

While doing some static analysis I came across the following piece of code at fs/cifs/smb2pdu.c:2017:

2017 if (n_iov > 2) {
2018 struct create_context *ccontext =
2019 (struct create_context *)iov[n_iov-1].iov_base;
2020 ccontext->Next =
2021 cpu_to_le32(iov[n_iov-1].iov_len);
2022 }

The code above is unreachable because n_iov is initialized to 2 and, its value is never updated. I'm not sure how to fix this.

Also, it seems there are multiple places in which memory allocated for *path* is leaking:

1946 else
1947 return -EIO;

1951 if (rc)
1952 return rc;

1987 if (rc) {
1988 cifs_small_buf_release(req);
1989 return rc;
1990 }

and more...

Thanks
--
Gustavo

#1 lore raw
Quoted 10 lines · Gustavo A. R. Silva

Hi Steve,

While doing some static analysis I came across the following piece of code at fs/cifs/smb2pdu.c:2017:

2017 if (n_iov > 2) {
2018 struct create_context *ccontext =
2019 (struct create_context *)iov[n_iov-1].iov_base;
2020 ccontext->Next =
2021 cpu_to_le32(iov[n_iov-1].iov_len);
2022 }

Good catch - this is harmless (and experimental mount option) - cut and paste - unneeded clause.
Fixing now

Quoted 5 lines

Also, it seems there are multiple places in which memory allocated for *path* is leaking:

1946 else
1947 return -EIO;

Quoted 7 lines

1951 if (rc)
1952 return rc;

1987 if (rc) {
1988 cifs_small_buf_release(req);
1989 return rc;
1990 }

Cleaning that up now. Will post a patch - thx.

Signature · 3 lines
Thanks,

Steve
Reviewed-by Aurelien Aptel
#2 lore raw

Gustavo,
Thx for pointing this out. Let me know if this patch addresses what you found. Code is experimental mount option but extremely important to get right due to move away from SMB1/CIFS which had posix extensions.

Quoted 38 lines · Steve French
Quoted 10 lines · Gustavo A. R. Silva

Hi Steve,

While doing some static analysis I came across the following piece of code at fs/cifs/smb2pdu.c:2017:

2017 if (n_iov > 2) {
2018 struct create_context *ccontext =
2019 (struct create_context *)iov[n_iov-1].iov_base;
2020 ccontext->Next =
2021 cpu_to_le32(iov[n_iov-1].iov_len);
2022 }

Good catch - this is harmless (and experimental mount option) - cut and paste - unneeded clause.
Fixing now

Quoted 5 lines

Also, it seems there are multiple places in which memory allocated for *path* is leaking:

1946 else
1947 return -EIO;

Quoted 7 lines

1951 if (rc)
1952 return rc;

1987 if (rc) {
1988 cifs_small_buf_release(req);
1989 return rc;
1990 }

Cleaning that up now. Will post a patch - thx.

--
Thanks,

Steve

Signature · 3 lines
Thanks,

Steve

From 0f4e3dec1c362119851aa2049ff23d1971b4e4a8 Mon Sep 17 00:00:00 2001
From: Steve French <[email protected]>
Date: Mon, 18 Jun 2018 12:02:47 -0500
Subject: [PATCH] smb3: fix memory leak in smb311_posix_mkdir

---
 fs/cifs/smb2pdu.c | 19 ++++++++++---------
 1 file changed, 10 insertions(+), 9 deletions(-)
fs/cifs/smb2pdu.c +10 -9
index 810b85787c91..b0498cadb952 100644
@@ -1943,13 +1943,17 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
 
 	if (ses && (ses->server))
 		server = ses->server;
-	else
+	else {
+		kfree(path);
 		return -EIO;
+	}
 
 	rc = smb2_plain_req_init(SMB2_CREATE, tcon, (void **) &req, &total_len);
 
-	if (rc)
+	if (rc) {
+		kfree(path);
 		return rc;
+	}
 
 	if (smb3_encryption_required(tcon))
 		flags |= CIFS_TRANSFORM_REQ;
@@ -1986,6 +1990,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
 						 tcon->treeName, path);
 		if (rc) {
 			cifs_small_buf_release(req);
+			kfree(path);
 			return rc;
 		}
 		req->NameLength = cpu_to_le16(name_len * 2);
@@ -2000,6 +2005,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
 			copy_path = kzalloc(copy_size, GFP_KERNEL);
 			if (!copy_path) {
 				cifs_small_buf_release(req);
+				kfree(path);
 				return -ENOMEM;
 			}
 			memcpy((char *)copy_path, (const char *)path,
@@ -2014,17 +2020,11 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
 	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);
-		}
-
 		rc = add_posix_context(iov, &n_iov, mode);
 		if (rc) {
 			cifs_small_buf_release(req);
 			kfree(copy_path);
+			kfree(path);
 			return rc;
 		}
 		pc_buf = iov[n_iov-1].iov_base;
@@ -2057,6 +2057,7 @@ int smb311_posix_mkdir(const unsigned int xid, struct inode *inode,
 
 smb311_mkdir_exit:
 	kfree(copy_path);
+	kfree(path);
 	kfree(pc_buf);
 	free_rsp_buf(resp_buftype, rsp);
 	return rc;
Signature · 1 line
2.17.1
author Reviewed-by
#3 lore raw

Hey Steve,

Quoted 6 lines · Steve French

Gustavo,
Thx for pointing this out. Let me know if this patch addresses what you found. Code is experimental mount option but extremely important to get right due to move away from SMB1/CIFS which had posix extensions.

Yep. It seems correct.

Thanks!
--
Gustavo

#4 lore raw

Aurelien spotted a problem with the patch - will resend to you

Quoted 18 lines · Gustavo A. R. Silva

Hey Steve,

Quoted 7 lines · Steve French

Gustavo,
Thx for pointing this out. Let me know if this patch addresses what you found. Code is experimental mount option but extremely important to get right due to move away from SMB1/CIFS which had posix extensions.

Yep. It seems correct.

Thanks!
--
Gustavo

Signature · 3 lines
Thanks,

Steve