Skip to contentSkip to conversation

ksmbd: fix leak of transform buffer on encrypt_resp() failure

PATCH In review Qianchang Zhao 2 participants 6 messages Nov 4, 2025 – Nov 8, 2025 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): 2025110432-maimed-polio-c7b4@gregkh

#1 lore raw

PATCH 1/1 ksmbd: fix leak of transform buffer on encrypt_resp() failure

When encrypt_resp() fails at the send path, we only set STATUS_DATA_ERROR but leave the transform buffer allocated (work->tr_buf in this tree). Repeating this path leaks kernel memory and can lead to OOM (DoS) when encryption is required.

Reproduced on: Linux v6.18-rc2 (self-built test kernel)

Fix by freeing the transform buffer and forcing plaintext error reply.

---
 fs/smb/server/server.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
fs/smb/server/server.c +5 -5
index 7b01c7589..15dd13e76 100644
@@ -246,11 +246,11 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
 		rc = conn->ops->encrypt_resp(work);
 		if (rc < 0) {
 			conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
-			 work->encrypted = false;
-    			 	if (work->tr_buf) {
-            				kvfree(work->tr_buf);
-            				work->tr_buf = NULL;
-       			   	}
+			work->encrypted = false;
+			if (work->tr_buf) {
+				kvfree(work->tr_buf);
+				work->tr_buf = NULL;
+			}
 		}
 	}
 	if (work->sess)
Signature · 1 line
2.34.1
maintainer
#2 lore raw
Quoted 26 lines · Qianchang Zhao

When encrypt_resp() fails at the send path, we only set STATUS_DATA_ERROR but leave the transform buffer allocated (work->tr_buf in this tree). Repeating this path leaks kernel memory and can lead to OOM (DoS) when encryption is required.

Reproduced on: Linux v6.18-rc2 (self-built test kernel)

Fix by freeing the transform buffer and forcing plaintext error reply.

---
 fs/smb/server/server.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
fs/smb/server/server.c +0 -0
index 7b01c7589..15dd13e76 100644
@@ -246,11 +246,11 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
                rc = conn->ops->encrypt_resp(work);
                if (rc < 0) {
                        conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);

fs/smb/server/server.c static void __handle_ksmbd_work(struct ksmbd_work *work, · line 253

Quoted 10 lines
fs/smb/server/server.c +5 -5
-                        work->encrypted = false;
-                               if (work->tr_buf) {
-                                       kvfree(work->tr_buf);
-                                       work->tr_buf = NULL;
-                                       }
+                       work->encrypted = false;
+                       if (work->tr_buf) {
+                               kvfree(work->tr_buf);
+                               work->tr_buf = NULL;
+                       }

This patch seems to be broken or wrong. Please check the patch again. Thanks!

Quoted 6 lines
fs/smb/server/server.c +0 -1
                }
        }
        if (work->sess)
--

2.34.1

#3 lore raw

PATCH 1/1 ksmbd: fix leak of transform buffer on encrypt_resp() failure

In reply to a message not in the archive

When encrypt_resp() fails at the send path, we only set STATUS_DATA_ERROR but leave the transform buffer allocated (work->tr_buf in this tree). Repeating this path leaks kernel memory and can lead to OOM (DoS) when encryption is required.

Reproduced on: Linux v6.18-rc2 (self-built test kernel)

Fix by freeing the transform buffer and forcing plaintext error reply.

---
 fs/smb/server/server.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
fs/smb/server/server.c +7 -1
index 40420544c..15dd13e76 100644
@@ -244,8 +244,14 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
 	if (work->sess && work->sess->enc && work->encrypted &&
 	    conn->ops->encrypt_resp) {
 		rc = conn->ops->encrypt_resp(work);
-		if (rc < 0)
+		if (rc < 0) {
 			conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
+			work->encrypted = false;
+			if (work->tr_buf) {
+				kvfree(work->tr_buf);
+				work->tr_buf = NULL;
+			}
+		}
 	}
 	if (work->sess)
 		ksmbd_user_session_put(work->sess);
Signature · 1 line
2.34.1
maintainer
#4 lore raw
Quoted 23 lines · Qianchang Zhao

When encrypt_resp() fails at the send path, we only set STATUS_DATA_ERROR but leave the transform buffer allocated (work->tr_buf in this tree). Repeating this path leaks kernel memory and can lead to OOM (DoS) when encryption is required.

Reproduced on: Linux v6.18-rc2 (self-built test kernel)

Fix by freeing the transform buffer and forcing plaintext error reply.

---
 fs/smb/server/server.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)
fs/smb/server/server.c +0 -0
index 40420544c..15dd13e76 100644

fs/smb/server/server.c static void __handle_ksmbd_work(struct ksmbd_work *work, · line 251

Quoted 9 lines
fs/smb/server/server.c +4 -1
@@ -244,8 +244,14 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
        if (work->sess && work->sess->enc && work->encrypted &&
            conn->ops->encrypt_resp) {
                rc = conn->ops->encrypt_resp(work);
-               if (rc < 0)
+               if (rc < 0) {
                        conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
+                       work->encrypted = false;
+                       if (work->tr_buf) {
+                               kvfree(work->tr_buf);

->tr_buf is freed in ksmbd_free_work_struct(). How can tr_buf not be freed? Thanks.

Quoted 9 lines
fs/smb/server/server.c +3 -1
+                               work->tr_buf = NULL;
+                       }
+               }
        }
        if (work->sess)
                ksmbd_user_session_put(work->sess);
--

2.34.1

#5 lore raw

PATCH v2 1/1 ksmbd: clear 'encrypted' on encrypt_resp() failure to send plaintext error

In reply to Qianchang Zhao

When encrypt_resp() fails in the send path, we set STATUS_DATA_ERROR but leave work->encrypted true. The send path then still assumes a valid transform buffer and tries to build/send an encrypted reply.

Clear work->encrypted on failure to force a plaintext error reply. The transform buffer (if allocated) is released by ksmbd_free_work_struct(), so no explicit kvfree(tr_buf) is needed.

---
v2:
- Drop explicit kvfree(tr_buf); it is freed in ksmbd_free_work_struct().
- Keep only 'work->encrypted = false' and update the commit message.

 fs/smb/server/server.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
fs/smb/server/server.c +3 -1
index 40420544c..a7444a78f 100644
@@ -244,8 +244,10 @@ static void __handle_ksmbd_work(struct ksmbd_work *work,
 	if (work->sess && work->sess->enc && work->encrypted &&
 	    conn->ops->encrypt_resp) {
 		rc = conn->ops->encrypt_resp(work);
-		if (rc < 0)
+		if (rc < 0) {
 			conn->ops->set_rsp_status(work, STATUS_DATA_ERROR);
+			work->encrypted = false;
+		}
 	}
 	if (work->sess)
 		ksmbd_user_session_put(work->sess);
Signature · 1 line
2.34.1
maintainer
#6 lore raw

Re: [PATCH v2] ksmbd: clear 'encrypted' on encrypt_resp() failure to send plaintext error

Quoted 6 lines · Qianchang Zhao

When encrypt_resp() fails in the send path, we set STATUS_DATA_ERROR but leave work->encrypted true. The send path then still assumes a valid transform buffer and tries to build/send an encrypted reply.

Clear work->encrypted on failure to force a plaintext error reply.

ksmbd will send a plain text error reply regardless of the work->encrypted value.
It doesn't seem to make any sense to set this to false. Thanks.