From: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
To: <ntfs3@lists.linux.dev>
Cc: Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
<linux-fsdevel@vger.kernel.org>
Subject: [PATCH 6/8] fs/ntfs3: Add more attributes checks in mi_enum_attr()
Date: Mon, 3 Jul 2023 11:27:21 +0400 [thread overview]
Message-ID: <18640b25-5018-ebf2-38d9-e750404cb66f@paragon-software.com> (raw)
In-Reply-To: <e41f6717-7c70-edf2-2d3a-8034840d14c5@paragon-software.com>
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
---
fs/ntfs3/record.c | 68 ++++++++++++++++++++++++++++++++++++-----------
1 file changed, 52 insertions(+), 16 deletions(-)
diff --git a/fs/ntfs3/record.c b/fs/ntfs3/record.c
index cae939cb42cf..53629b1f65e9 100644
--- a/fs/ntfs3/record.c
+++ b/fs/ntfs3/record.c
@@ -199,8 +199,9 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi,
struct ATTRIB *attr)
{
const struct MFT_REC *rec = mi->mrec;
u32 used = le32_to_cpu(rec->used);
- u32 t32, off, asize;
+ u32 t32, off, asize, prev_type;
u16 t16;
+ u64 data_size, alloc_size, tot_size;
if (!attr) {
u32 total = le32_to_cpu(rec->total);
@@ -219,6 +220,7 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi,
struct ATTRIB *attr)
if (!is_rec_inuse(rec))
return NULL;
+ prev_type = 0;
attr = Add2Ptr(rec, off);
} else {
/* Check if input attr inside record. */
@@ -232,11 +234,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi,
struct ATTRIB *attr)
return NULL;
}
- if (off + asize < off) {
- /* Overflow check. */
+ /* Overflow check. */
+ if (off + asize < off)
return NULL;
- }
+ prev_type = le32_to_cpu(attr->type);
attr = Add2Ptr(attr, asize);
off += asize;
}
@@ -256,7 +258,11 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi,
struct ATTRIB *attr)
/* 0x100 is last known attribute for now. */
t32 = le32_to_cpu(attr->type);
- if ((t32 & 0xf) || (t32 > 0x100))
+ if (!t32 || (t32 & 0xf) || (t32 > 0x100))
+ return NULL;
+
+ /* attributes in record must be ordered by type */
+ if (t32 < prev_type)
return NULL;
/* Check overflow and boundary. */
@@ -265,16 +271,15 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi,
struct ATTRIB *attr)
/* Check size of attribute. */
if (!attr->non_res) {
+ /* Check resident fields. */
if (asize < SIZEOF_RESIDENT)
return NULL;
t16 = le16_to_cpu(attr->res.data_off);
-
if (t16 > asize)
return NULL;
- t32 = le32_to_cpu(attr->res.data_size);
- if (t16 + t32 > asize)
+ if (t16 + le32_to_cpu(attr->res.data_size) > asize)
return NULL;
t32 = sizeof(short) * attr->name_len;
@@ -284,21 +289,52 @@ struct ATTRIB *mi_enum_attr(struct mft_inode *mi,
struct ATTRIB *attr)
return attr;
}
- /* Check some nonresident fields. */
- if (attr->name_len &&
- le16_to_cpu(attr->name_off) + sizeof(short) * attr->name_len >
- le16_to_cpu(attr->nres.run_off)) {
+ /* Check nonresident fields. */
+ if (attr->non_res != 1)
+ return NULL;
+
+ t16 = le16_to_cpu(attr->nres.run_off);
+ if (t16 > asize)
+ return NULL;
+
+ t32 = sizeof(short) * attr->name_len;
+ if (t32 && le16_to_cpu(attr->name_off) + t32 > t16)
+ return NULL;
+
+ /* Check start/end vcn. */
+ if (le64_to_cpu(attr->nres.svcn) > le64_to_cpu(attr->nres.evcn) + 1)
+ return NULL;
+
+ data_size = le64_to_cpu(attr->nres.data_size);
+ if (le64_to_cpu(attr->nres.valid_size) > data_size)
return NULL;
- }
- if (attr->nres.svcn || !is_attr_ext(attr)) {
+ alloc_size = le64_to_cpu(attr->nres.alloc_size);
+ if (data_size > alloc_size)
+ return NULL;
+
+ t32 = mi->sbi->cluster_mask;
+ if (alloc_size & t32)
+ return NULL;
+
+ if (!attr->nres.svcn && is_attr_ext(attr)) {
+ /* First segment of sparse/compressed attribute */
+ if (asize + 8 < SIZEOF_NONRESIDENT_EX)
+ return NULL;
+
+ tot_size = le64_to_cpu(attr->nres.total_size);
+ if (tot_size & t32)
+ return NULL;
+
+ if (tot_size > alloc_size)
+ return NULL;
+ } else {
if (asize + 8 < SIZEOF_NONRESIDENT)
return NULL;
if (attr->nres.c_unit)
return NULL;
- } else if (asize + 8 < SIZEOF_NONRESIDENT_EX)
- return NULL;
+ }
return attr;
}
--
2.34.1
next prev parent reply other threads:[~2023-07-03 7:27 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-03 7:23 [PATCH 0/8] fs/ntfs3: Bugfix and refactoring Konstantin Komarov
2023-07-03 7:24 ` [PATCH 1/8] fs/ntfs3: Add ckeck in ni_update_parent() Konstantin Komarov
2023-07-03 7:25 ` [PATCH 2/8] fs/ntfs3: Write immediately updated ntfs state Konstantin Komarov
2023-07-03 7:25 ` [PATCH 3/8] fs/ntfs3: Minor code refactoring and formatting Konstantin Komarov
2023-07-03 7:26 ` [PATCH 4/8] fs/ntfs3: Don't allow to change label if volume is read-only Konstantin Komarov
2023-07-03 7:26 ` [PATCH 5/8] fs/ntfs3: Use kvmalloc instead of kmalloc(... __GFP_NOWARN) Konstantin Komarov
2023-12-23 4:46 ` Matthew Wilcox
2023-12-23 13:33 ` Tetsuo Handa
2023-12-23 16:56 ` Matthew Wilcox
2023-07-03 7:27 ` Konstantin Komarov [this message]
2023-07-03 7:27 ` [PATCH 7/8] fs/ntfs3: fix deadlock in mark_as_free_ex Konstantin Komarov
2023-07-03 7:28 ` [PATCH 8/8] fs/ntfs3: Fix shift-out-of-bounds in ntfs_fill_super Konstantin Komarov
2023-12-23 5:00 ` [PATCH 0/8] fs/ntfs3: Bugfix and refactoring Kent Overstreet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=18640b25-5018-ebf2-38d9-e750404cb66f@paragon-software.com \
--to=almaz.alexandrovich@paragon-software.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=ntfs3@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox