Commit b83cb25c authored by Namjae Jeon's avatar Namjae Jeon Committed by Yongjian Sun
Browse files

ksmbd: fix out-of-bounds in parse_sec_desc()

mainline inclusion
from mainline-v6.12-rc3
commit d6e13e19063db24f94b690159d0633aaf72a0f03
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IBY448
CVE: CVE-2025-21946

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d6e13e19063db24f94b690159d0633aaf72a0f03



--------------------------------

If osidoffset, gsidoffset and dacloffset could be greater than smb_ntsd
struct size. If it is smaller, It could cause slab-out-of-bounds.
And when validating sid, It need to check it included subauth array size.

Cc: stable@vger.kernel.org
Reported-by: default avatarNorbert Szetei <norbert@doyensec.com>
Tested-by: default avatarNorbert Szetei <norbert@doyensec.com>
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
Signed-off-by: default avatarYongjian Sun <sunyongjian1@huawei.com>
parent 3e5da20e
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -807,6 +807,13 @@ static int parse_sid(struct smb_sid *psid, char *end_of_acl)
		return -EINVAL;
	}

	if (!psid->num_subauth)
		return 0;

	if (psid->num_subauth > SID_MAX_SUB_AUTHORITIES ||
	    end_of_acl < (char *)psid + 8 + sizeof(__le32) * psid->num_subauth)
		return -EINVAL;

	return 0;
}

@@ -848,6 +855,9 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
	pntsd->type = cpu_to_le16(DACL_PRESENT);

	if (pntsd->osidoffset) {
		if (le32_to_cpu(pntsd->osidoffset) < sizeof(struct smb_ntsd))
			return -EINVAL;

		rc = parse_sid(owner_sid_ptr, end_of_acl);
		if (rc) {
			pr_err("%s: Error %d parsing Owner SID\n", __func__, rc);
@@ -863,6 +873,9 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
	}

	if (pntsd->gsidoffset) {
		if (le32_to_cpu(pntsd->gsidoffset) < sizeof(struct smb_ntsd))
			return -EINVAL;

		rc = parse_sid(group_sid_ptr, end_of_acl);
		if (rc) {
			pr_err("%s: Error %d mapping Owner SID to gid\n",
@@ -884,6 +897,9 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
		pntsd->type |= cpu_to_le16(DACL_PROTECTED);

	if (dacloffset) {
		if (dacloffset < sizeof(struct smb_ntsd))
			return -EINVAL;

		parse_dacl(idmap, dacl_ptr, end_of_acl,
			   owner_sid_ptr, group_sid_ptr, fattr);
	}