From: Eugene Korenevsky <ekorenevsky@aliyun.com> mainline inclusion from mainline-v6.18-rc2 commit 6447b0e355562a1ff748c4a2ffb89aae7e84d2c9 category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/7774 CVE: CVE-2025-40099 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Malicious SMB server can send invalid reply to FSCTL_DFS_GET_REFERRALS - reply smaller than sizeof(struct get_dfs_referral_rsp) - reply with number of referrals smaller than NumberOfReferrals in the header Processing of such replies will cause oob. Return -EINVAL error on such replies to prevent oob-s. Signed-off-by: Eugene Korenevsky <ekorenevsky@aliyun.com> Cc: stable@vger.kernel.org Suggested-by: Nathan Chancellor <nathan@kernel.org> Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Signed-off-by: Steve French <stfrench@microsoft.com> Signed-off-by: Wang Zhaolong <wangzhaolong@huaweicloud.com> --- fs/smb/client/misc.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c index fb4abb1a7b2f..2d32cf5bb17d 100644 --- a/fs/smb/client/misc.c +++ b/fs/smb/client/misc.c @@ -905,19 +905,36 @@ parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size, { int i, rc = 0; char *data_end; struct dfs_referral_level_3 *ref; + if (rsp_size < sizeof(*rsp)) { + cifs_dbg(VFS | ONCE, + "%s: header is malformed (size is %u, must be %zu)\n", + __func__, rsp_size, sizeof(*rsp)); + rc = -EINVAL; + goto parse_DFS_referrals_exit; + } + *num_of_nodes = le16_to_cpu(rsp->NumberOfReferrals); if (*num_of_nodes < 1) { cifs_dbg(VFS | ONCE, "%s: [path=%s] num_referrals must be at least > 0, but we got %d\n", __func__, searchName, *num_of_nodes); rc = -ENOENT; goto parse_DFS_referrals_exit; } + if (sizeof(*rsp) + *num_of_nodes * sizeof(REFERRAL3) > rsp_size) { + cifs_dbg(VFS | ONCE, + "%s: malformed buffer (size is %u, must be at least %zu)\n", + __func__, rsp_size, + sizeof(*rsp) + *num_of_nodes * sizeof(REFERRAL3)); + rc = -EINVAL; + goto parse_DFS_referrals_exit; + } + ref = (struct dfs_referral_level_3 *) &(rsp->referrals); if (ref->VersionNumber != cpu_to_le16(3)) { cifs_dbg(VFS, "Referrals of V%d version are not supported, should be V3\n", le16_to_cpu(ref->VersionNumber)); rc = -EINVAL; -- 2.34.3