mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
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:
parent
eeb5ef6083
commit
b09d092eb2
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user