smb: client: fix missing iov bounds check in parse_posix_sids()

In parse_posix_sids(), sidsbuf_end is calculated using the server-supplied
out_len without being validated against the actual length of the received
iov (iov_len).

If a server provides an inflated out_len, sidsbuf_end will point past the
end of the iov. This defeats the bounds guards in posix_info_sid_size(),
allowing out-of-bounds reads into adjacent kernel memory.

Fix this by rejecting responses where the calculated sidsbuf_end would
exceed the received iov boundaries or cause pointer wraparound.

Fixes: a90f37e3d7ac ("smb: client: parse owner/group when creating reparse points")
Cc: stable@vger.kernel.org
Signed-off-by: Frank Sorenson <sorenson@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
This commit is contained in:
Frank Sorenson 2026-09-16 16:33:58 -05:00 committed by Paulo Alcantara
parent eeb5ef6083
commit b09d092eb2

View File

@ -77,6 +77,17 @@ static int parse_posix_sids(struct cifs_open_info_data *data,
sidsbuf = (u8 *)qi + le16_to_cpu(qi->OutputBufferOffset) + qi_len;
sidsbuf_end = sidsbuf + out_len - qi_len;
if (sidsbuf_end < sidsbuf) {
cifs_dbg(VFS, "%s: server-supplied out_len %u caused pointer wraparound\n",
__func__, out_len);
return -EINVAL;
}
if (sidsbuf_end > (u8 *)rsp_iov->iov_base + rsp_iov->iov_len) {
cifs_dbg(VFS, "%s: server-supplied out_len %u overruns iov by %td bytes\n",
__func__, out_len,
sidsbuf_end - ((u8 *)rsp_iov->iov_base + rsp_iov->iov_len));
return -EINVAL;
}
owner_len = posix_info_sid_size(sidsbuf, sidsbuf_end);
if (owner_len == -1)