[PATCH 0/3] smb: client: validate SMB1 write and query response lengths
From: Diego Oliva
Date: Fri Sep 11 2026 - 11:32:29 EST
Three fixes for SMB1 reply parsers that dereference a response struct
without first establishing that the response was long enough to hold
it. They are the same class of defect as the recent "smb: client:
reject short READ responses in CIFSSMBRead()", generalised to the
write and legacy query paths.
checkSMB() only requires the RFC1002 length to agree with WordCount
and the byte count; it does not check either against what the command
in question requires. Every fixed-layout SMB1 response struct is
therefore unguarded unless its own parser checks: a reply carrying a
smaller WordCount than the command expects is accepted and handed to
the parser with rc == 0, and the smallest such reply is 35 bytes, a
header with WordCount and ByteCount both zero.
Patch 1 adds the missing minimum-length check to the three WRITE_RSP
parsers, and patch 3 does the same for SMBQueryInformation(). In each
case the size required is exactly the smallest reply a conforming
server can send for the word count the response is documented to
carry, so no legitimate server can be rejected:
sizeof(WRITE_RSP) wct = 6 33 + 2*6 + 2 = 47
sizeof(QUERY_INFORMATION_RSP) wct = 10 33 + 2*10 + 2 = 55
where 33 is sizeof(struct smb_hdr) and the trailing 2 is ByteCount.
Patch 2 is a different bug in one of the same parsers.
cifs_writev_callback() accepts a byte count larger than the length it
asked to write - the existing OS/2 workaround only masks off the high
16 bits - and hands it to netfs, which answers with a WARN() from
netfs_write_subrequest_terminated(). Before netfs clamps the value,
cifs_write_subrequest_terminated() has already used it to grow the
client's idea of the file size. Reject the reply instead.
All three use smb_EIO2(), introduced in v6.19, so they do not apply to
older stable trees as-is, and substituting plain -EIO is not enough on
its own: older trees shape struct smb_hdr and struct mid_q_entry
differently, so both the sizeof() bounds these patches test against and
the response length patch 1 reads out of the mid need reworking.
Diego Oliva (3):
smb: client: reject short WRITE responses in the SMB1 write paths
smb: client: reject over-long write counts in cifs_writev_callback()
smb: client: reject short responses in SMBQueryInformation()
fs/smb/client/cifssmb.c | 36 ++++++++++++++++++++++++++++++++++++
fs/smb/client/trace.h | 3 +++
2 files changed, 39 insertions(+)
base-commit: 0a96d0d726cd380423ac38e2c28f538db2940a1d
--
2.39.5