[PATCH] fs/ntfs3: convert to non-resident when the new size exceeds the record size

From: Konstantin Komarov

Date: Thu Sep 03 2026 - 14:50:32 EST


attr_set_size_res() only checked whether the attribute still fits when
the attribute was growing (dsize > 0), and only against
sbi->max_bytes_per_attr. A resident attribute could therefore be
resized to a value larger than a single MFT record can hold.

Move the check ahead of the memmove() paths and also reject a new size
larger than sbi->record_size, falling back to attr_make_nonresident()
in both cases.

Signed-off-by: Konstantin Komarov <almaz.alexandrovich@xxxxxxxxxxxxxxxxxxxx>
---
fs/ntfs3/attrib.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c
index b1c315206ffa..833731d799a4 100644
--- a/fs/ntfs3/attrib.c
+++ b/fs/ntfs3/attrib.c
@@ -394,13 +394,15 @@ static int attr_set_size_res(struct ntfs_inode *ni, struct ATTRIB *attr,
char *next = Add2Ptr(attr, asize);
s64 dsize = ALIGN(new_size, 8) - ALIGN(rsize, 8);

+ if (new_size > sbi->record_size ||
+ (dsize > 0 && used + dsize > sbi->max_bytes_per_attr)) {
+ return attr_make_nonresident(ni, attr, le, mi, new_size, run,
+ ins_attr, NULL);
+ }
+
if (dsize < 0) {
memmove(next + dsize, next, tail);
} else if (dsize > 0) {
- if (used + dsize > sbi->max_bytes_per_attr)
- return attr_make_nonresident(ni, attr, le, mi, new_size,
- run, ins_attr, NULL);
-
memmove(next + dsize, next, tail);
memset(next, 0, dsize);
}
--
2.43.0