summaryrefslogtreecommitdiff
path: root/fs/smb/server/smb2pdu.c
diff options
context:
space:
mode:
authorNamjae Jeon <linkinjeon@kernel.org>2023-08-19 20:26:17 +0900
committerSteve French <stfrench@microsoft.com>2023-08-29 12:30:19 -0500
commit041bba4414cda37d00063952c9bff9c3d5812a19 (patch)
treebe4ef69bdd54c6e0b94acc877e5873f93f8c65a7 /fs/smb/server/smb2pdu.c
parente2b76ab8b5c9327ab2dae6da05d0752eb2f4771d (diff)
ksmbd: fix wrong interim response on compound
If smb2_lock or smb2_open request is compound, ksmbd could send wrong interim response to client. ksmbd allocate new interim buffer instead of using resonse buffer to support compound request. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/smb/server/smb2pdu.c')
-rw-r--r--fs/smb/server/smb2pdu.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 14354e2787d9..95520bf8aa16 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -153,8 +153,8 @@ void smb2_set_err_rsp(struct ksmbd_work *work)
err_rsp->ByteCount = 0;
err_rsp->ErrorData[0] = 0;
err = ksmbd_iov_pin_rsp(work, (void *)err_rsp,
- work->conn->vals->header_size +
- SMB2_ERROR_STRUCTURE_SIZE2);
+ __SMB2_HEADER_STRUCTURE_SIZE +
+ SMB2_ERROR_STRUCTURE_SIZE2);
if (err)
work->send_no_response = 1;
}
@@ -709,13 +709,24 @@ void release_async_work(struct ksmbd_work *work)
void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status)
{
struct smb2_hdr *rsp_hdr;
+ struct ksmbd_work *in_work = ksmbd_alloc_work_struct();
- rsp_hdr = ksmbd_resp_buf_next(work);
- smb2_set_err_rsp(work);
+ if (allocate_interim_rsp_buf(in_work)) {
+ pr_err("smb_allocate_rsp_buf failed!\n");
+ ksmbd_free_work_struct(in_work);
+ return;
+ }
+
+ in_work->conn = work->conn;
+ memcpy(smb2_get_msg(in_work->response_buf), ksmbd_resp_buf_next(work),
+ __SMB2_HEADER_STRUCTURE_SIZE);
+
+ rsp_hdr = smb2_get_msg(in_work->response_buf);
+ smb2_set_err_rsp(in_work);
rsp_hdr->Status = status;
- ksmbd_conn_write(work);
- rsp_hdr->Status = 0;
+ ksmbd_conn_write(in_work);
+ ksmbd_free_work_struct(in_work);
}
static __le32 smb2_get_reparse_tag_special_file(umode_t mode)
@@ -7049,8 +7060,6 @@ skip:
list_del(&work->fp_entry);
spin_unlock(&fp->f_lock);
- ksmbd_iov_reset(work);
-
if (work->state != KSMBD_WORK_ACTIVE) {
list_del(&smb_lock->llist);
spin_lock(&work->conn->llist_lock);
@@ -7068,7 +7077,6 @@ skip:
goto out;
}
- init_smb2_rsp_hdr(work);
rsp->hdr.Status =
STATUS_RANGE_NOT_LOCKED;
kfree(smb_lock);