Skip to content

Commit 70d3855

Browse files
m-brodschiaalexandrovich
authored andcommitted
ntfs3: Allocate iomap inline_data using alloc_page
This fixes a BUG reported in iomap_write_end_inline: iomap_inline_data_valid checks that the inline_data fits within a page. If the inline_data is allocated with kmemdup there's no guarantee that it's page-aligned, so the check sometimes fails. Allocate it with alloc_page to ensure it's page-aligned. Closes: https://bugzilla.kernel.org/show_bug.cgi?id=221446 Fixes: 099ef9a ("fs/ntfs3: implement iomap-based file operations") Signed-off-by: Mihai Brodschi <m.brodschi@gmail.com> Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
1 parent 723325d commit 70d3855

2 files changed

Lines changed: 9 additions & 5 deletions

File tree

fs/ntfs3/attrib.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1001,6 +1001,7 @@ int attr_data_get_block_locked(struct ntfs_inode *ni, CLST vcn, CLST clen,
10011001
struct ATTRIB *attr, *attr_b;
10021002
struct ATTR_LIST_ENTRY *le, *le_b;
10031003
struct mft_inode *mi, *mi_b;
1004+
struct page *page;
10041005
CLST hint, svcn, to_alloc, evcn1, next_svcn, asize, end, vcn0;
10051006
CLST alloc, evcn;
10061007
unsigned fr;
@@ -1036,10 +1037,13 @@ int attr_data_get_block_locked(struct ntfs_inode *ni, CLST vcn, CLST clen,
10361037
*lcn = RESIDENT_LCN;
10371038
*len = data_size;
10381039
if (res && data_size) {
1039-
*res = kmemdup(resident_data(attr_b), data_size,
1040-
GFP_KERNEL);
1041-
if (!*res)
1040+
page = alloc_page(GFP_KERNEL);
1041+
if (!page) {
10421042
err = -ENOMEM;
1043+
} else {
1044+
*res = page_address(page);
1045+
memcpy(*res, resident_data(attr_b), data_size);
1046+
}
10431047
}
10441048
goto out;
10451049
}

fs/ntfs3/inode.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -796,7 +796,7 @@ static int ntfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
796796

797797
if (lcn == RESIDENT_LCN) {
798798
if (offset >= clen) {
799-
kfree(res);
799+
__free_page(virt_to_page(res));
800800
if (flags & IOMAP_REPORT) {
801801
/* special code for report. */
802802
return -ENOENT;
@@ -920,7 +920,7 @@ static int ntfs_iomap_end(struct inode *inode, loff_t pos, loff_t length,
920920

921921
out:
922922
if (iomap->type == IOMAP_INLINE) {
923-
kfree(iomap->private);
923+
__free_page(virt_to_page(iomap->private));
924924
iomap->private = NULL;
925925
}
926926

0 commit comments

Comments
 (0)