diff mbox series

ksmbd: validate length in fsctl_pipe_transceive()

Message ID 20220504224801.2900034-1-mmakassikis@freebox.fr (mailing list archive)
State New, archived
Headers show
Series ksmbd: validate length in fsctl_pipe_transceive() | expand

Commit Message

Marios Makassikis May 4, 2022, 10:48 p.m. UTC
The InputCount field contains the number of bytes that should be copied
from the buffer, starting at the InputOffset.

Change to code to:
 - validate InputCount with regards to the buffer length
 - read data from InputOffset, rather than ->Buffer, as there may be
 padding present

Signed-off-by: Marios Makassikis <mmakassikis@freebox.fr>
---
 fs/ksmbd/smb2pdu.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c
index 23b47e505e2b..7e4051479993 100644
--- a/fs/ksmbd/smb2pdu.c
+++ b/fs/ksmbd/smb2pdu.c
@@ -7432,12 +7432,23 @@  static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id,
 				 struct smb2_ioctl_req *req,
 				 struct smb2_ioctl_rsp *rsp)
 {
-	struct ksmbd_rpc_command *rpc_resp;
-	char *data_buf = (char *)&req->Buffer[0];
+	struct ksmbd_rpc_command *rpc_resp = NULL;
+	char *data_buf;
 	int nbytes = 0;
+	size_t length;
 
-	rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf,
-				   le32_to_cpu(req->InputCount));
+	length = le32_to_cpu(req->InputCount);
+
+	if ((u64)le32_to_cpu(req->InputOffset) + length >
+	    get_rfc1002_len(work->request_buf) - 4) {
+		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
+		goto out;
+	}
+
+	data_buf = (char *)(((char *)&req->hdr.ProtocolId) +
+			   le32_to_cpu(req->InputOffset));
+
+	rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf, length);
 	if (rpc_resp) {
 		if (rpc_resp->flags == KSMBD_RPC_SOME_NOT_MAPPED) {
 			/*