Commit cc225902 authored by Konstantin Komarov's avatar Konstantin Komarov Committed by Yifan Qiao
Browse files

fs/ntfs3: Add a check for attr_names and oatbl

stable inclusion
from stable-v6.6.43
commit f3124d51e4e7b56a732419d8dc270e807252334f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAG8T5
CVE: CVE-2024-41018

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



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

commit 702d4930eb06dcfda85a2fa67e8a1a27bfa2a845 upstream.

Added out-of-bound checking for *ane (ATTR_NAME_ENTRY).

Reported-by: default avatarlei lu <llfamsec@gmail.com>
Fixes: 865e7a7700d93 ("fs/ntfs3: Reduce stack usage")
Signed-off-by: default avatarKonstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarYifan Qiao <qiaoyifan4@huawei.com>
parent a080e375
Loading
Loading
Loading
Loading
+32 −6
Original line number Diff line number Diff line
@@ -3722,6 +3722,8 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)

	u64 rec_lsn, checkpt_lsn = 0, rlsn = 0;
	struct ATTR_NAME_ENTRY *attr_names = NULL;
	u32 attr_names_bytes = 0;
	u32 oatbl_bytes = 0;
	struct RESTART_TABLE *dptbl = NULL;
	struct RESTART_TABLE *trtbl = NULL;
	const struct RESTART_TABLE *rt;
@@ -3736,6 +3738,7 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
	struct NTFS_RESTART *rst = NULL;
	struct lcb *lcb = NULL;
	struct OPEN_ATTR_ENRTY *oe;
	struct ATTR_NAME_ENTRY *ane;
	struct TRANSACTION_ENTRY *tr;
	struct DIR_PAGE_ENTRY *dp;
	u32 i, bytes_per_attr_entry;
@@ -4314,17 +4317,40 @@ int log_replay(struct ntfs_inode *ni, bool *initialized)
	lcb = NULL;

check_attribute_names2:
	if (rst->attr_names_len && oatbl) {
		struct ATTR_NAME_ENTRY *ane = attr_names;
		while (ane->off) {
	if (attr_names && oatbl) {
		off = 0;
		for (;;) {
			/* Check we can use attribute name entry 'ane'. */
			static_assert(sizeof(*ane) == 4);
			if (off + sizeof(*ane) > attr_names_bytes) {
				/* just ignore the rest. */
				break;
			}

			ane = Add2Ptr(attr_names, off);
			t16 = le16_to_cpu(ane->off);
			if (!t16) {
				/* this is the only valid exit. */
				break;
			}

			/* Check we can use open attribute entry 'oe'. */
			if (t16 + sizeof(*oe) > oatbl_bytes) {
				/* just ignore the rest. */
				break;
			}

			/* TODO: Clear table on exit! */
			oe = Add2Ptr(oatbl, le16_to_cpu(ane->off));
			oe = Add2Ptr(oatbl, t16);
			t16 = le16_to_cpu(ane->name_bytes);
			off += t16 + sizeof(*ane);
			if (off > attr_names_bytes) {
				/* just ignore the rest. */
				break;
			}
			oe->name_len = t16 / sizeof(short);
			oe->ptr = ane->name;
			oe->is_attr_name = 2;
			ane = Add2Ptr(ane,
				      sizeof(struct ATTR_NAME_ENTRY) + t16);
		}
	}