aboutsummaryrefslogtreecommitdiffstats
path: root/fs/smb/client/misc.c
diff options
context:
space:
mode:
authorEugene Korenevsky <ekorenevsky@aliyun.com>2025-10-13 21:39:30 +0300
committerSteve French <stfrench@microsoft.com>2025-10-15 22:10:28 -0500
commit6447b0e355562a1ff748c4a2ffb89aae7e84d2c9 (patch)
tree3116023e821cff099b4c699a4325b02dfbd19b80 /fs/smb/client/misc.c
parentsmb: client: Fix refcount leak for cifs_sb_tlink (diff)
downloadlinux-6447b0e355562a1ff748c4a2ffb89aae7e84d2c9.tar.gz
linux-6447b0e355562a1ff748c4a2ffb89aae7e84d2c9.zip
cifs: parse_dfs_referrals: prevent oob on malformed input
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>
Diffstat (limited to '')
-rw-r--r--fs/smb/client/misc.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/smb/client/misc.c b/fs/smb/client/misc.c
index dda6dece802a..e10123d8cd7d 100644
--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -916,6 +916,14 @@ parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size,
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) {
@@ -925,6 +933,15 @@ parse_dfs_referrals(struct get_dfs_referral_rsp *rsp, u32 rsp_size,
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",