From: Namjae Jeon <linkinjeon@kernel.org> To: linux-cifs@vger.kernel.org Cc: "Namjae Jeon" <linkinjeon@kernel.org>, "Ronnie Sahlberg" <ronniesahlberg@gmail.com>, "Ralph Böhme" <slow@samba.org>, "Steve French" <smfrench@gmail.com> Subject: [PATCH v2 2/4] ksmbd: add validation in smb2_ioctl Date: Sun, 19 Sep 2021 11:13:13 +0900 [thread overview] Message-ID: <20210919021315.642856-3-linkinjeon@kernel.org> (raw) In-Reply-To: <20210919021315.642856-1-linkinjeon@kernel.org> Add validation for request/response buffer size check in smb2_ioctl. Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com> Cc: Ralph Böhme <slow@samba.org> Cc: Steve French <smfrench@gmail.com> Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> --- v2: - fix warning: variable 'ret' is used uninitialized ret. fs/ksmbd/smb2pdu.c | 56 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c index 7763f69e1ae8..6ea50a9ac64e 100644 --- a/fs/ksmbd/smb2pdu.c +++ b/fs/ksmbd/smb2pdu.c @@ -7021,7 +7021,7 @@ static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req, unsigned int i, chunk_count, chunk_count_written = 0; unsigned int chunk_size_written = 0; loff_t total_size_written = 0; - int ret, cnt_code; + int ret = 0, cnt_code; cnt_code = le32_to_cpu(req->CntCode); ci_req = (struct copychunk_ioctl_req *)&req->Buffer[0]; @@ -7038,6 +7038,8 @@ static int fsctl_copychunk(struct ksmbd_work *work, struct smb2_ioctl_req *req, chunks = (struct srv_copychunk *)&ci_req->Chunks[0]; chunk_count = le32_to_cpu(ci_req->ChunkCount); + if (chunk_count == 0) + goto out; total_size_written = 0; /* verify the SRV_COPYCHUNK_COPY packet */ @@ -7142,7 +7144,8 @@ static __be32 idev_ipv4_address(struct in_device *idev) static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, struct smb2_ioctl_req *req, - struct smb2_ioctl_rsp *rsp) + struct smb2_ioctl_rsp *rsp, + int out_buf_len) { struct network_interface_info_ioctl_rsp *nii_rsp = NULL; int nbytes = 0; @@ -7225,6 +7228,8 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, sockaddr_storage->addr6.ScopeId = 0; } + if (out_buf_len < sizeof(struct network_interface_info_ioctl_rsp)) + break; nbytes += sizeof(struct network_interface_info_ioctl_rsp); } rtnl_unlock(); @@ -7245,11 +7250,16 @@ static int fsctl_query_iface_info_ioctl(struct ksmbd_conn *conn, static int fsctl_validate_negotiate_info(struct ksmbd_conn *conn, struct validate_negotiate_info_req *neg_req, - struct validate_negotiate_info_rsp *neg_rsp) + struct validate_negotiate_info_rsp *neg_rsp, + int in_buf_len) { int ret = 0; int dialect; + if (in_buf_len < sizeof(struct validate_negotiate_info_req) + + le16_to_cpu(neg_req->DialectCount) * sizeof(__le16)) + return -EINVAL; + dialect = ksmbd_lookup_dialect_by_id(neg_req->Dialects, neg_req->DialectCount); if (dialect == BAD_PROT_ID || dialect != conn->dialect) { @@ -7425,7 +7435,7 @@ int smb2_ioctl(struct ksmbd_work *work) struct smb2_ioctl_req *req; struct smb2_ioctl_rsp *rsp, *rsp_org; int cnt_code, nbytes = 0; - int out_buf_len; + int out_buf_len, in_buf_len; u64 id = KSMBD_NO_FID; struct ksmbd_conn *conn = work->conn; int ret = 0; @@ -7455,6 +7465,7 @@ int smb2_ioctl(struct ksmbd_work *work) cnt_code = le32_to_cpu(req->CntCode); out_buf_len = le32_to_cpu(req->MaxOutputResponse); out_buf_len = min(KSMBD_IPC_MAX_PAYLOAD, out_buf_len); + in_buf_len = le32_to_cpu(req->InputCount); switch (cnt_code) { case FSCTL_DFS_GET_REFERRALS: @@ -7490,9 +7501,16 @@ int smb2_ioctl(struct ksmbd_work *work) goto out; } + if (in_buf_len < sizeof(struct validate_negotiate_info_req)) + return -EINVAL; + + if (out_buf_len < sizeof(struct validate_negotiate_info_rsp)) + return -EINVAL; + ret = fsctl_validate_negotiate_info(conn, (struct validate_negotiate_info_req *)&req->Buffer[0], - (struct validate_negotiate_info_rsp *)&rsp->Buffer[0]); + (struct validate_negotiate_info_rsp *)&rsp->Buffer[0], + in_buf_len); if (ret < 0) goto out; @@ -7501,7 +7519,8 @@ int smb2_ioctl(struct ksmbd_work *work) rsp->VolatileFileId = cpu_to_le64(SMB2_NO_FID); break; case FSCTL_QUERY_NETWORK_INTERFACE_INFO: - nbytes = fsctl_query_iface_info_ioctl(conn, req, rsp); + nbytes = fsctl_query_iface_info_ioctl(conn, req, rsp, + out_buf_len); if (nbytes < 0) goto out; break; @@ -7528,6 +7547,11 @@ int smb2_ioctl(struct ksmbd_work *work) goto out; } + if (in_buf_len < sizeof(struct copychunk_ioctl_req)) { + ret = -EINVAL; + goto out; + } + if (out_buf_len < sizeof(struct copychunk_ioctl_rsp)) { ret = -EINVAL; goto out; @@ -7537,6 +7561,11 @@ int smb2_ioctl(struct ksmbd_work *work) fsctl_copychunk(work, req, rsp); break; case FSCTL_SET_SPARSE: + if (in_buf_len < sizeof(struct file_sparse)) { + ret = -EINVAL; + goto out; + } + ret = fsctl_set_sparse(work, id, (struct file_sparse *)&req->Buffer[0]); if (ret < 0) @@ -7555,6 +7584,11 @@ int smb2_ioctl(struct ksmbd_work *work) goto out; } + if (in_buf_len < sizeof(struct file_zero_data_information)) { + ret = -EINVAL; + goto out; + } + zero_data = (struct file_zero_data_information *)&req->Buffer[0]; @@ -7574,6 +7608,11 @@ int smb2_ioctl(struct ksmbd_work *work) break; } case FSCTL_QUERY_ALLOCATED_RANGES: + if (in_buf_len < sizeof(struct file_allocated_range_buffer)) { + ret = -EINVAL; + goto out; + } + ret = fsctl_query_allocated_ranges(work, id, (struct file_allocated_range_buffer *)&req->Buffer[0], (struct file_allocated_range_buffer *)&rsp->Buffer[0], @@ -7614,6 +7653,11 @@ int smb2_ioctl(struct ksmbd_work *work) struct duplicate_extents_to_file *dup_ext; loff_t src_off, dst_off, length, cloned; + if (in_buf_len < sizeof(struct duplicate_extents_to_file)) { + ret = -EINVAL; + goto out; + } + dup_ext = (struct duplicate_extents_to_file *)&req->Buffer[0]; fp_in = ksmbd_lookup_fd_slow(work, dup_ext->VolatileFileHandle, -- 2.25.1
next prev parent reply other threads:[~2021-09-19 2:13 UTC|newest] Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top 2021-09-19 2:13 [PATCH v2 1/4] ksmbd: add request buffer validation in smb2_set_info Namjae Jeon 2021-09-19 2:13 ` [PATCH] ksmbd: use LOOKUP_NO_SYMLINKS flags for default lookup Namjae Jeon 2021-09-19 2:13 ` Namjae Jeon [this message] 2021-09-21 8:08 ` [PATCH v2 2/4] ksmbd: add validation in smb2_ioctl Ralph Boehme 2021-09-21 11:15 ` Namjae Jeon 2021-09-19 2:13 ` [PATCH v2 3/4] ksmbd: add validation for FILE_FULL_EA_INFORMATION of smb2_get_info Namjae Jeon 2021-09-21 8:09 ` Ralph Boehme 2021-09-19 2:13 ` [PATCH v2 4/4] ksmbd: add buffer validation for SMB2_CREATE_CONTEXT Namjae Jeon 2021-09-21 8:32 ` Ralph Boehme 2021-09-22 0:26 ` Namjae Jeon 2021-09-20 14:45 ` [PATCH v2 1/4] ksmbd: add request buffer validation in smb2_set_info Ralph Boehme 2021-09-20 15:03 ` Ralph Boehme 2021-09-20 15:10 ` Steve French 2021-09-20 16:11 ` Ralph Boehme 2021-09-20 16:20 ` Steve French 2021-09-20 16:30 ` Ralph Boehme 2021-09-20 15:38 ` Ralph Boehme 2021-09-20 16:18 ` Namjae Jeon 2021-09-21 14:23 ` Tom Talpey 2021-09-22 2:31 ` Namjae Jeon 2021-09-22 3:40 ` Namjae Jeon 2021-09-22 18:39 ` Tom Talpey
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20210919021315.642856-3-linkinjeon@kernel.org \ --to=linkinjeon@kernel.org \ --cc=linux-cifs@vger.kernel.org \ --cc=ronniesahlberg@gmail.com \ --cc=slow@samba.org \ --cc=smfrench@gmail.com \ --subject='Re: [PATCH v2 2/4] ksmbd: add validation in smb2_ioctl' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).