NACK/Cmnt: [SRU][R][PATCH v2 1/1] ntfs3: use page allocation for resident attribute inline data

Viktor Pashaiev w.paszajew at gmail.com
Fri Sep 18 11:12:16 UTC 2026


Hi Andrei,

Thanks for the clarification and for checking the Resolute tree.

Good to know that commit 18c7ba7a1e6d already landed via LP: #2164666.
I will follow up on LP: #2165844 to reference that commit and close
out the bug once the kernel lands in proposed.

Also noted regarding the cover letter placement for future kernel submissions.

Thanks!
Viktor Pashaiev

pt., 18 wrz 2026 o 13:02 Andrei Gherzan <andrei.gherzan at canonical.com>
napisaƂ(a):
>
> On 2026/09/17 07:24PM, Viktor Pashaiev wrote:
> > From: Namjae Jeon <linkinjeon at kernel.org>
> >
> > BugLink: https://bugs.launchpad.net/bugs/2165844
> >
> > SRU Justification:
> >
> > [ Impact ]
> >
> > Any buffered write() to an ntfs3-mounted volume can trigger a kernel BUG in
> > the generic iomap write path and panic the kernel:
> >   kernel BUG at fs/iomap/buffered-io.c:1061!
> >   RIP: 0010:iomap_write_end+0x...
> >
> > This crash is reachable from unprivileged userspace with a plain write(2)
> > syscall (e.g. file copy, rsync, or appending data). Small files with resident
> > attribute data allocate inline_data using kmemdup() from slab. Because slab
> > allocations rarely start at the beginning of a physical page (i.e.
> > offset_in_page(inline_data) > 0), when the file size plus that offset exceeds
> > PAGE_SIZE (4096 bytes), iomap_inline_data_valid() fails and hits the BUG_ON
> > assertion, immediately crashing the system.
> >
> > [ Fix ]
> >
> > Backport upstream commit 36ee1313199b7f16bf963c6ac0241861585125d9:
> > "fs/ntfs3: Use page allocation for resident attribute inline data".
> >
> > Replace kmemdup() with alloc_page(GFP_NOFS | __GFP_ZERO) so that
> > page_address() is always strictly page-aligned (offset_in_page == 0).
> > Update the cleanup path to put_page() accordingly.
> > For Ubuntu 7.0 (resolute), paths are adjusted from fs/ntfs/ (upstream 7.1+)
> > to fs/ntfs3/ (Ubuntu 7.0 kernel driver location).
> >
> > [ Test Plan ]
> >
> > 1. Create and mount an NTFS filesystem:
> >    mkfs.ntfs -Q -F /dev/loopX
> >    mount -t ntfs3 /dev/loopX /mnt
> > 2. Perform buffered writes on small resident files near the 4KB boundary
> >    from an unprivileged account.
> >    Without the fix: triggers immediate kernel BUG_ON at fs/iomap/buffered-io.c:1061.
> >    With the fix: write completes successfully without panic, and data integrity
> >    is verified upon unmount/remount.
> >
> > [ Where problems could occur ]
> >
> > The change is strictly isolated to resident attribute handling in fs/ntfs3.
> > Instead of allocating arbitrary slab chunks, a single dedicated page is
> > allocated and immediately released via put_page() upon completion of the
> > iomap operation. The memory overhead is negligible (4KB transient per active
> > resident write), and non-resident attributes or other filesystems are
> > completely unaffected.
> >
> > [ Other Info ]
> >
> > This fix was requested by Benjamin Wheeler in LP: #2165844.
> > The backport was verified with independent clean builds on linux-source-7.0.0
> > against both 7.0.0-31-generic and 7.0.0-30-generic headers, and git am
> > applies cleanly without offsets or warnings.
> >
> > (backported from commit 36ee1313199b7f16bf963c6ac0241861585125d9)
>
> The cover letter should only be in the cover email not copied in the
> backported/cherry-picked commit. I think I generated this confusion because on
> your initial submission the cover letter went in spam.
>
> Also, this fix is already in Resolute:
>
> 18c7ba7a1e6d ntfs3: Allocate iomap inline_data using alloc_page
>   BugLink: https://bugs.launchpad.net/bugs/2164666
>   [ Upstream commit 70d3855594cf6e8791970714b65cac3202d6160e ]
>   Fixes: 099ef9ab9203 ("fs/ntfs3: implement iomap-based file operations")
>
> > [Viktor Pashaiev: adjusted file paths from fs/ntfs/ to fs/ntfs3/ for 7.0]
> > Signed-off-by: Namjae Jeon <linkinjeon at kernel.org>
> > Signed-off-by: Viktor Pashaiev <w.paszajew at gmail.com>
> > ---
> >  fs/ntfs3/attrib.c | 10 +++++++---
> >  fs/ntfs3/inode.c  |  6 +++---
> >  2 files changed, 10 insertions(+), 6 deletions(-)
> >
> > --- a/fs/ntfs3/attrib.c
> > +++ b/fs/ntfs3/attrib.c
> > @@ -1042,10 +1042,14 @@ int attr_data_get_block_locked(struct ntfs_inode *ni, CLST vcn, CLST clen,
> >               *lcn = RESIDENT_LCN;
> >               *len = data_size;
> >               if (res && data_size) {
> > -                     *res = kmemdup(resident_data(attr_b), data_size,
> > -                                    GFP_KERNEL);
> > -                     if (!*res)
> > +                     struct page *page = alloc_page(GFP_NOFS | __GFP_ZERO);
> > +                     if (page) {
> > +                             memcpy(page_address(page), resident_data(attr_b),
> > +                                    data_size);
> > +                             *res = page;
> > +                     } else {
> >                               err = -ENOMEM;
> > +                     }
> >               }
> >               goto out;
> >       }
> > --- a/fs/ntfs3/inode.c
> > +++ b/fs/ntfs3/inode.c
> > @@ -845,7 +845,7 @@ static int ntfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> >
> >       if (lcn == RESIDENT_LCN) {
> >               if (offset >= clen) {
> > -                     kfree(res);
> > +                     put_page((struct page *)res);
> >                       if (flags & IOMAP_REPORT) {
> >                               /* special code for report. */
> >                               return -ENOENT;
> > @@ -853,7 +853,8 @@ static int ntfs_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
> >                       return -EFAULT;
> >               }
> >
> > -             iomap->private = iomap->inline_data = res;
> > +             iomap->private = res;
> > +             iomap->inline_data = page_address((struct page *)res);
> >               iomap->type = IOMAP_INLINE;
> >               iomap->offset = 0;
> >               iomap->length = clen; /* resident size in bytes. */
> > @@ -965,7 +966,7 @@ static int ntfs_iomap_end(struct inode *inode, loff_t pos, loff_t length,
> >
> >  out:
> >       if (iomap->type == IOMAP_INLINE) {
> > -             kfree(iomap->private);
> > +             put_page((struct page *)iomap->private);
> >               iomap->private = NULL;
> >       }
> >
> > --
> > 2.43.0
> >
> > --
> > kernel-team mailing list
> > kernel-team at lists.ubuntu.com
> > https://lists.ubuntu.com/mailman/listinfo/kernel-team
>
> --
> Andrei Gherzan
> gpg: rsa4096/D4D94F67AD0E9640



More information about the kernel-team mailing list