Commit 543963cd authored by lei lu's avatar lei lu Committed by openeuler-sync-bot
Browse files

ntfs3: Add bounds checking to mi_enum_attr()

stable inclusion
from stable-v6.6.60
commit 22cdf3be7d34f61a91b9e2966fec3a29f3871398
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB37AN
CVE: CVE-2024-50248

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=22cdf3be7d34f61a91b9e2966fec3a29f3871398



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

[ Upstream commit 556bdf27c2dd5c74a9caacbe524b943a6cd42d99 ]

Added bounds checking to make sure that every attr don't stray beyond
valid memory region.

Signed-off-by: default avatarlei lu <llfamsec@gmail.com>
Signed-off-by: default avatarKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>

Conflicts:
	fs/ntfs3/record.c
[Context differences.]
Signed-off-by: default avatarBaokun Li <libaokun1@huawei.com>
(cherry picked from commit 3870f87a)
parent d26629f1
Loading
Loading
Loading
Loading
+10 −9
Original line number Diff line number Diff line
@@ -211,24 +211,19 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
		prev_type = 0;
		attr = Add2Ptr(rec, off);
	} else {
		/* Check if input attr inside record. */
		/*
		 * We don't need to check previous attr here. There is
		 * a bounds checking in the previous round.
		 */
		off = PtrOffset(rec, attr);
		if (off >= used)
			return NULL;

		asize = le32_to_cpu(attr->size);
		if (asize < SIZEOF_RESIDENT) {
			/* Impossible 'cause we should not return such attribute. */
			return NULL;
		}

		prev_type = le32_to_cpu(attr->type);
		attr = Add2Ptr(attr, asize);
		off += asize;
	}

	asize = le32_to_cpu(attr->size);

	/* Can we use the first field (attr->type). */
	if (off + 8 > used) {
		static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8);
@@ -249,6 +244,12 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
	if (t32 < prev_type)
		return NULL;

	asize = le32_to_cpu(attr->size);
	if (asize < SIZEOF_RESIDENT) {
		/* Impossible 'cause we should not return such attribute. */
		return NULL;
	}

	/* Check boundary. */
	if (off + asize > used)
		return NULL;