From: Sasha Levin <sashal@kernel.org>
To: stable@vger.kernel.org
Cc: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>,
Namjae Jeon <linkinjeon@kernel.org>,
Paulo Alcantara <pc@manguebit.org>,
Sasha Levin <sashal@kernel.org>
Subject: [PATCH 5.10.y] smb: client: validate NT transaction response layout and offsets
Date: Thu, 5 Nov 2026 14:42:26 -0500 [thread overview]
Message-ID: <20261105193918.2652018-1-sashal@kernel.org> (raw)
In-Reply-To: <2026110455-observing-blush-5a37@gregkh>
From: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
[ Upstream commit 83d0d5e0ca22233c75daf139ec0063b9d2ff1ac7 ]
validate_ntransact() assumes that the response uses the fixed 18-word NT
transaction layout. A different WordCount makes get_bcc() locate the byte
count at a different offset from pSMBr->ByteCount, allowing the subsequent
bounds checks to use inconsistent response boundaries.
The function also turns the 32-bit ParameterOffset and DataOffset fields
into pointers before checking their bounds. On a 32-bit client, a large
offset can wrap the pointer below end_of_smb and pass the one-sided pointer
comparison. The caller then dereferences the parameter pointer or copies
from the data pointer.
Require the expected WordCount before reading the byte count. Check each
offset and count against the received SMB length as integers before forming
either pointer. Use subtraction after validating the offset so that the
range checks cannot overflow.
Reported-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
Fixes: 0a4b92c05ed0 ("[CIFS] Add worker function for Get ACL cifs style")
Cc: stable@vger.kernel.org
Signed-off-by: Ratnaker Gautam <ratnaker.gautam@kuleuven.be>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/cifs/cifssmb.c | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 67ff1669cab2a..9af7ddd21d4f1 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -3843,9 +3843,10 @@ static int
validate_ntransact(char *buf, char **ppparm, char **ppdata,
__u32 *pparmlen, __u32 *pdatalen)
{
- char *end_of_smb;
__u32 data_count, data_offset, parm_count, parm_offset;
struct smb_com_ntransact_rsp *pSMBr;
+ size_t buflen;
+ char *end_buf;
u16 bcc;
*pdatalen = 0;
@@ -3856,37 +3857,42 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata,
pSMBr = (struct smb_com_ntransact_rsp *)buf;
+ if (pSMBr->hdr.WordCount != 18) {
+ cifs_dbg(FYI, "invalid NT transaction WordCount %u\n",
+ pSMBr->hdr.WordCount);
+ return -EINVAL;
+ }
+
bcc = get_bcc(&pSMBr->hdr);
- end_of_smb = 2 /* sizeof byte count */ + bcc +
- (char *)&pSMBr->ByteCount;
+ end_buf = 2 /* sizeof byte count */ + bcc + (char *)&pSMBr->ByteCount;
+ buflen = end_buf - buf;
data_offset = le32_to_cpu(pSMBr->DataOffset);
data_count = le32_to_cpu(pSMBr->DataCount);
parm_offset = le32_to_cpu(pSMBr->ParameterOffset);
parm_count = le32_to_cpu(pSMBr->ParameterCount);
- *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset;
- *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset;
-
/* should we also check that parm and data areas do not overlap? */
- if (*ppparm > end_of_smb) {
+ if (parm_offset > buflen) {
cifs_dbg(FYI, "parms start after end of smb\n");
return -EINVAL;
- } else if (parm_count + *ppparm > end_of_smb) {
+ } else if (parm_count > buflen - parm_offset) {
cifs_dbg(FYI, "parm end after end of smb\n");
return -EINVAL;
- } else if (*ppdata > end_of_smb) {
+ } else if (data_offset > buflen) {
cifs_dbg(FYI, "data starts after end of smb\n");
return -EINVAL;
- } else if (data_count + *ppdata > end_of_smb) {
- cifs_dbg(FYI, "data %p + count %d (%p) past smb end %p start %p\n",
- *ppdata, data_count, (data_count + *ppdata),
- end_of_smb, pSMBr);
+ } else if (data_count > buflen - data_offset) {
+ cifs_dbg(FYI, "data offset %u + count %u past smb length %zu\n",
+ data_offset, data_count, buflen);
return -EINVAL;
} else if (parm_count + data_count > bcc) {
cifs_dbg(FYI, "parm count and data count larger than SMB\n");
return -EINVAL;
}
+
+ *ppparm = buf + parm_offset;
+ *ppdata = buf + data_offset;
*pdatalen = data_count;
*pparmlen = parm_count;
return 0;
--
2.53.0
prev parent reply other threads:[~2026-11-05 19:42 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 18:34 FAILED: patch "[PATCH] smb: client: validate NT transaction response layout and" failed to apply to 5.10-stable tree gregkh
2026-11-05 19:42 ` Sasha Levin [this message]
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=20261105193918.2652018-1-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=linkinjeon@kernel.org \
--cc=pc@manguebit.org \
--cc=ratnaker.gautam@kuleuven.be \
--cc=stable@vger.kernel.org \
/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
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox