Unverified Commit bba47b34 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!13398 [sync] PR-13342: ntfs3: fix CVE-2024-50248

Merge Pull Request from: @openeuler-sync-bot 
 

Origin pull request: 
https://gitee.com/openeuler/kernel/pulls/13342 
 
PR sync from: Baokun Li <libaokun1@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/ASAFNSPLGRWBA727WDLZZK7W6FYMNVIM/ 
Konstantin Komarov (1):
  fs/ntfs3: Sequential field availability check in mi_enum_attr()

lei lu (1):
  ntfs3: Add bounds checking to mi_enum_attr()


-- 
2.46.1
 
https://gitee.com/src-openeuler/kernel/issues/IB37AN 
 
Link:https://gitee.com/openeuler/kernel/pulls/13398

 

Reviewed-by: default avatarLi Nan <linan122@huawei.com>
Signed-off-by: default avatarLi Nan <linan122@huawei.com>
parents 5a632b3f e3aa2b02
Loading
Loading
Loading
Loading
+13 −13
Original line number Diff line number Diff line
@@ -211,25 +211,21 @@ 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). */
	/* NOTE: this code also checks attr->size availability. */
	if (off + 8 > used) {
		static_assert(ALIGN(sizeof(enum ATTR_TYPE), 8) == 8);
		return NULL;
@@ -249,6 +245,8 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
	if (t32 < prev_type)
		return NULL;

	asize = le32_to_cpu(attr->size);

	/* Check boundary. */
	if (off + asize > used)
		return NULL;
@@ -278,6 +276,10 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
	if (attr->non_res != 1)
		return NULL;

	/* Can we use memory including attr->nres.valid_size? */
	if (asize < SIZEOF_NONRESIDENT)
		return NULL;

	t16 = le16_to_cpu(attr->nres.run_off);
	if (t16 > asize)
		return NULL;
@@ -304,7 +306,8 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)

	if (!attr->nres.svcn && is_attr_ext(attr)) {
		/* First segment of sparse/compressed attribute */
		if (asize + 8 < SIZEOF_NONRESIDENT_EX)
		/* Can we use memory including attr->nres.total_size? */
		if (asize < SIZEOF_NONRESIDENT_EX)
			return NULL;

		tot_size = le64_to_cpu(attr->nres.total_size);
@@ -314,9 +317,6 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi, struct ATTRIB *attr)
		if (tot_size > alloc_size)
			return NULL;
	} else {
		if (asize + 8 < SIZEOF_NONRESIDENT)
			return NULL;

		if (attr->nres.c_unit)
			return NULL;