[PATCH OLK-5.10 0/2] CVE-2026-97563 and CVE-2026-97565
Diego Oliva (2): smb: client: reject short READ responses in CIFSSMBRead() smb: client: reject out-of-bounds DataOffset in CIFSSMBRead() fs/cifs/cifssmb.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) -- 2.52.0
From: Diego Oliva <diego@bynar.io> mainline inclusion from mainline-v7.3-rc3 commit e6142a8bfc230c7263eb8b0475249c958ce49367 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/20155 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- CIFSSMBRead() reads DataLengthHigh, DataLength and DataOffset out of the READ_RSP returned by the server without first checking that a whole READ_RSP was actually received. The length of the response is recorded in rsp_iov.iov_len, but nothing constrains it to be at least read_rsp_size before those fields are dereferenced. A malicious or compromised SMB1 server can return a response shorter than the READ_RSP header, so that parsing the header itself reads past the end of the receive buffer. SMB1 is not negotiated by default; reaching this code requires an explicit vers=1.0 mount. Reject the response unless it is at least read_rsp_size bytes long. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Suggested-by: Paulo Alcantara <pc@manguebit.org> Cc: stable@vger.kernel.org # 6.19.x Assisted-by: Bynario AI Signed-off-by: Diego Oliva <diego@bynar.io> Reviewed-by: David Howells <dhowells@redhat.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org> Signed-off-by: Yifan Qiao <qiaoyifan4@huawei.com> --- fs/cifs/cifssmb.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 643729b498a0..3b3330f36f34 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1804,6 +1804,13 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms, pSMBr = (READ_RSP *)rsp_iov.iov_base; if (rc) { cifs_dbg(VFS, "Send error in read = %d\n", rc); + } else if (rsp_iov.iov_len < tcon->ses->server->vals->read_rsp_size) { + /* check that the received response can hold a whole READ_RSP */ + cifs_dbg(FYI, "%s: server returned short header. got=%zu expected=%zu\n", + __func__, rsp_iov.iov_len, + tcon->ses->server->vals->read_rsp_size); + rc = -EIO; + *nbytes = 0; } else { int data_length = le16_to_cpu(pSMBr->DataLengthHigh); data_length = data_length << 16; -- 2.52.0
From: Diego Oliva <diego@bynar.io> mainline inclusion from mainline-v7.3-rc3 commit 5be5bdda5863eacc964b609ba927764f253431b3 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/20155 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- The SMB1 synchronous read helper CIFSSMBRead() validates the server's DataLength against CIFSMaxBufSize and the caller's count, but never validates DataOffset. The copy source is formed as &pSMBr->hdr.Protocol + le16_to_cpu(pSMBr->DataOffset) and memcpy()'d for DataLength bytes with no check that the [DataOffset, DataOffset + DataLength) range lies within the response actually received from the server. A malicious or compromised SMB1 server can return a response carrying an in-range DataLength and a large DataOffset, driving the source pointer past the end of the response buffer. The memcpy() then copies adjacent kernel heap into the caller's read buffer (information disclosure), or reads unmapped memory and oopses (denial of service). SMB1 is not negotiated by default; reaching this code requires an explicit vers=1.0 mount. Both DataOffset and the received response length recorded in rsp_iov.iov_len are relative to the start of the SMB header, so reject the response unless DataOffset + DataLength fits within that length, using overflow-safe arithmetic, before forming the source pointer. The response length has been validated by the previous patch, so the DataOffset and DataLength fields can be read safely here. While here, make data_length unsigned. It holds a length derived from unsigned on-the-wire fields and is only ever compared against unsigned quantities; print it with %u accordingly, and add __func__ to the cifs_dbg() calls in this function. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Cc: stable@vger.kernel.org # 6.19.x Assisted-by: Bynario AI Signed-off-by: Diego Oliva <diego@bynar.io> Reviewed-by: David Howells <dhowells@redhat.com> Signed-off-by: Paulo Alcantara <pc@manguebit.org> Conflicts: fs/smb/client/cifssmb.c fs/smb/client/trace.h [Context differences.] Signed-off-by: Yifan Qiao <qiaoyifan4@huawei.com> --- fs/cifs/cifssmb.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 3b3330f36f34..030d3cd4e3fb 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1812,7 +1812,8 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms, rc = -EIO; *nbytes = 0; } else { - int data_length = le16_to_cpu(pSMBr->DataLengthHigh); + unsigned int data_length = le16_to_cpu(pSMBr->DataLengthHigh); + __u16 data_offset = le16_to_cpu(pSMBr->DataOffset); data_length = data_length << 16; data_length += le16_to_cpu(pSMBr->DataLength); *nbytes = data_length; @@ -1824,9 +1825,15 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms, data_length, count); rc = -EIO; *nbytes = 0; + } else if (4 + data_offset < sizeof(*pSMBr) || + 4 + (size_t)data_offset + data_length > rsp_iov.iov_len) { + /* check that the data lies within the received response */ + cifs_dbg(FYI, "%s: bad data offset %u length %u for response of %zu\n", + __func__, data_offset, data_length, rsp_iov.iov_len); + rc = -EIO; + *nbytes = 0; } else { - pReadData = (char *) (&pSMBr->hdr.Protocol) + - le16_to_cpu(pSMBr->DataOffset); + pReadData = (char *) (&pSMBr->hdr.Protocol) + data_offset; /* if (rc = copy_to_user(buf, pReadData, data_length)) { cifs_dbg(VFS, "Faulting on read rc = %d\n",rc); rc = -EFAULT; -- 2.52.0
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/30024 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/N5H... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/30024 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/N5H...
participants (2)
-
patchwork bot -
Yifan Qiao