* [PATCH] mm/shmem: fix uninitialized folio in shmem_symlink @ 2025-12-24 9:40 Barry Song 2025-12-24 17:01 ` Matthew Wilcox 0 siblings, 1 reply; 5+ messages in thread From: Barry Song @ 2025-12-24 9:40 UTC (permalink / raw) To: akpm, linux-mm Cc: linux-kernel, Barry Song, Hugh Dickins, Baolin Wang, syzbot+178fff6149127421c2cc From: Barry Song <baohua@kernel.org> Uninitialized folio allocated in shmem_symlink() may be accessed during swap-out, causing KMSAN BUG: BUG: KMSAN: uninit-value in is_folio_zero_filled mm/page_io.c:188 [inline] BUG: KMSAN: uninit-value in swap_writeout+0x468/0x1390 mm/page_io.c:263 is_folio_zero_filled mm/page_io.c:188 [inline] swap_writeout+0x468/0x1390 mm/page_io.c:263 shmem_writeout+0x1abb/0x1f60 mm/shmem.c:1662 writeout mm/vmscan.c:649 [inline] pageout mm/vmscan.c:698 [inline] shrink_folio_list+0x5920/0x7fc0 mm/vmscan.c:1418 evict_folios+0x999d/0xbf30 mm/vmscan.c:4711 try_to_shrink_lruvec+0x12b6/0x17e0 mm/vmscan.c:4874 lru_gen_shrink_lruvec mm/vmscan.c:5023 [inline] shrink_lruvec+0x46f/0x4f10 mm/vmscan.c:5784 shrink_node_memcgs mm/vmscan.c:6020 [inline] This patch clears the remaining part to zero for the portion not covered by memcpy from symname. Cc: Hugh Dickins <hughd@google.com> Cc: Baolin Wang <baolin.wang@linux.alibaba.com> Reported-by: syzbot+178fff6149127421c2cc@syzkaller.appspotmail.com Closes: https://lore.kernel.org/lkml/6949370f.050a0220.1b4e0c.0038.GAE@google.com/ Signed-off-by: Barry Song <baohua@kernel.org> --- mm/shmem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mm/shmem.c b/mm/shmem.c index ec6c01378e9d..835900a08f51 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -4131,6 +4131,7 @@ static int shmem_symlink(struct mnt_idmap *idmap, struct inode *dir, goto out_remove_offset; inode->i_op = &shmem_symlink_inode_operations; memcpy(folio_address(folio), symname, len); + folio_zero_range(folio, len, folio_size(folio) - len); folio_mark_uptodate(folio); folio_mark_dirty(folio); folio_unlock(folio); -- 2.43.0 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mm/shmem: fix uninitialized folio in shmem_symlink 2025-12-24 9:40 [PATCH] mm/shmem: fix uninitialized folio in shmem_symlink Barry Song @ 2025-12-24 17:01 ` Matthew Wilcox 2025-12-25 4:04 ` Barry Song 0 siblings, 1 reply; 5+ messages in thread From: Matthew Wilcox @ 2025-12-24 17:01 UTC (permalink / raw) To: Barry Song Cc: akpm, linux-mm, linux-kernel, Barry Song, Hugh Dickins, Baolin Wang, syzbot+178fff6149127421c2cc On Wed, Dec 24, 2025 at 10:40:27PM +1300, Barry Song wrote: > From: Barry Song <baohua@kernel.org> > > Uninitialized folio allocated in shmem_symlink() may be accessed > during swap-out, causing KMSAN BUG: This would be an unfortunate way to fix it. The vast majority of symlinks are short, and we'll never access past the \0 in normal operation, so we'll be dirtying a lot of cachelines essentially to (1) shut up an automated tool and (2) optimise a corner case. How about this instead which delays zeroing to swapout? diff --git a/mm/shmem.c b/mm/shmem.c index ec6c01378e9d..f3b3be1b50fe 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -1636,6 +1636,13 @@ int shmem_writeout(struct folio *folio, struct swap_iocb **plug, folio_mark_uptodate(folio); } + /* Zero out symlink tails to help with compression */ + if (folio_test_owner_2(folio)) { + struct inode *inode = folio->mapping->host; + folio_zero_segment(folio, inode->i_size, folio_size(folio)); + folio_clear_owner_2(folio); + } + if (!folio_alloc_swap(folio)) { bool first_swapped = shmem_recalc_inode(inode, 0, nr_pages); int error; @@ -4133,6 +4140,7 @@ static int shmem_symlink(struct mnt_idmap *idmap, struct inode *dir, memcpy(folio_address(folio), symname, len); folio_mark_uptodate(folio); folio_mark_dirty(folio); + folio_set_owner_2(folio); folio_unlock(folio); folio_put(folio); } ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mm/shmem: fix uninitialized folio in shmem_symlink 2025-12-24 17:01 ` Matthew Wilcox @ 2025-12-25 4:04 ` Barry Song 2025-12-25 10:08 ` Baolin Wang 2025-12-28 4:29 ` Matthew Wilcox 0 siblings, 2 replies; 5+ messages in thread From: Barry Song @ 2025-12-25 4:04 UTC (permalink / raw) To: Matthew Wilcox Cc: akpm, linux-mm, linux-kernel, Hugh Dickins, Baolin Wang, syzbot+178fff6149127421c2cc On Thu, Dec 25, 2025 at 6:01 AM Matthew Wilcox <willy@infradead.org> wrote: > > On Wed, Dec 24, 2025 at 10:40:27PM +1300, Barry Song wrote: > > From: Barry Song <baohua@kernel.org> > > > > Uninitialized folio allocated in shmem_symlink() may be accessed > > during swap-out, causing KMSAN BUG: > > This would be an unfortunate way to fix it. The vast majority of > symlinks are short, and we'll never access past the \0 in normal > operation, so we'll be dirtying a lot of cachelines essentially to (1) > shut up an automated tool and (2) optimise a corner case. > > How about this instead which delays zeroing to swapout? Matthew, thank you very much for your review, even during Christmas. I would like to wish you a happy holiday! I am not quite sure, as shm symlinks do not seem very common. Since allocating a folio requires a symname longer than 128 bytes (where 128 == SHORT_SYMLINK_LEN), such cases appear even rarer. BTW, do we need to migrate the owner_2 flag in folio_migrate_flags()? If so, I am not quite sure it is worth changing the hotpath to accommodate this. > > diff --git a/mm/shmem.c b/mm/shmem.c > index ec6c01378e9d..f3b3be1b50fe 100644 > --- a/mm/shmem.c > +++ b/mm/shmem.c > @@ -1636,6 +1636,13 @@ int shmem_writeout(struct folio *folio, struct swap_iocb **plug, > folio_mark_uptodate(folio); > } > > + /* Zero out symlink tails to help with compression */ > + if (folio_test_owner_2(folio)) { > + struct inode *inode = folio->mapping->host; > + folio_zero_segment(folio, inode->i_size, folio_size(folio)); > + folio_clear_owner_2(folio); > + } > + > if (!folio_alloc_swap(folio)) { > bool first_swapped = shmem_recalc_inode(inode, 0, nr_pages); > int error; > @@ -4133,6 +4140,7 @@ static int shmem_symlink(struct mnt_idmap *idmap, struct inode *dir, > memcpy(folio_address(folio), symname, len); > folio_mark_uptodate(folio); > folio_mark_dirty(folio); > + folio_set_owner_2(folio); > folio_unlock(folio); > folio_put(folio); > } Thanks Barry ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mm/shmem: fix uninitialized folio in shmem_symlink 2025-12-25 4:04 ` Barry Song @ 2025-12-25 10:08 ` Baolin Wang 2025-12-28 4:29 ` Matthew Wilcox 1 sibling, 0 replies; 5+ messages in thread From: Baolin Wang @ 2025-12-25 10:08 UTC (permalink / raw) To: Barry Song, Matthew Wilcox Cc: akpm, linux-mm, linux-kernel, Hugh Dickins, syzbot+178fff6149127421c2cc On 2025/12/25 12:04, Barry Song wrote: > On Thu, Dec 25, 2025 at 6:01 AM Matthew Wilcox <willy@infradead.org> wrote: >> >> On Wed, Dec 24, 2025 at 10:40:27PM +1300, Barry Song wrote: >>> From: Barry Song <baohua@kernel.org> >>> >>> Uninitialized folio allocated in shmem_symlink() may be accessed >>> during swap-out, causing KMSAN BUG: >> >> This would be an unfortunate way to fix it. The vast majority of >> symlinks are short, and we'll never access past the \0 in normal >> operation, so we'll be dirtying a lot of cachelines essentially to (1) >> shut up an automated tool and (2) optimise a corner case. >> >> How about this instead which delays zeroing to swapout? > > Matthew, thank you very much for your review, even during Christmas. > I would like to wish you a happy holiday! > > I am not quite sure, as shm symlinks do not seem very common. Since > allocating a folio requires a symname longer than 128 bytes (where > 128 == SHORT_SYMLINK_LEN), such cases appear even rarer. > > BTW, do we need to migrate the owner_2 flag in folio_migrate_flags()? > If so, I am not quite sure it is worth changing the hotpath to > accommodate this. +1. At least for me, using the 'PG_owner_2' flag alone to mark this uncommon case doesn't seem quite worthwhile. >> diff --git a/mm/shmem.c b/mm/shmem.c >> index ec6c01378e9d..f3b3be1b50fe 100644 >> --- a/mm/shmem.c >> +++ b/mm/shmem.c >> @@ -1636,6 +1636,13 @@ int shmem_writeout(struct folio *folio, struct swap_iocb **plug, >> folio_mark_uptodate(folio); >> } >> >> + /* Zero out symlink tails to help with compression */ >> + if (folio_test_owner_2(folio)) { >> + struct inode *inode = folio->mapping->host; >> + folio_zero_segment(folio, inode->i_size, folio_size(folio)); >> + folio_clear_owner_2(folio); >> + } >> + >> if (!folio_alloc_swap(folio)) { >> bool first_swapped = shmem_recalc_inode(inode, 0, nr_pages); >> int error; >> @@ -4133,6 +4140,7 @@ static int shmem_symlink(struct mnt_idmap *idmap, struct inode *dir, >> memcpy(folio_address(folio), symname, len); >> folio_mark_uptodate(folio); >> folio_mark_dirty(folio); >> + folio_set_owner_2(folio); >> folio_unlock(folio); >> folio_put(folio); >> } > > Thanks > Barry ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] mm/shmem: fix uninitialized folio in shmem_symlink 2025-12-25 4:04 ` Barry Song 2025-12-25 10:08 ` Baolin Wang @ 2025-12-28 4:29 ` Matthew Wilcox 1 sibling, 0 replies; 5+ messages in thread From: Matthew Wilcox @ 2025-12-28 4:29 UTC (permalink / raw) To: Barry Song Cc: akpm, linux-mm, linux-kernel, Hugh Dickins, Baolin Wang, syzbot+178fff6149127421c2cc On Thu, Dec 25, 2025 at 05:04:38PM +1300, Barry Song wrote: > On Thu, Dec 25, 2025 at 6:01 AM Matthew Wilcox <willy@infradead.org> wrote: > > > > On Wed, Dec 24, 2025 at 10:40:27PM +1300, Barry Song wrote: > > > From: Barry Song <baohua@kernel.org> > > > > > > Uninitialized folio allocated in shmem_symlink() may be accessed > > > during swap-out, causing KMSAN BUG: > > > > This would be an unfortunate way to fix it. The vast majority of > > symlinks are short, and we'll never access past the \0 in normal > > operation, so we'll be dirtying a lot of cachelines essentially to (1) > > shut up an automated tool and (2) optimise a corner case. > > > > How about this instead which delays zeroing to swapout? > > Matthew, thank you very much for your review, even during Christmas. > I would like to wish you a happy holiday! Heh, thanks. My mailserver is actually in a different timezone from me, so it was still the 24th when I sent it ;-) > I am not quite sure, as shm symlinks do not seem very common. Since > allocating a folio requires a symname longer than 128 bytes (where > 128 == SHORT_SYMLINK_LEN), such cases appear even rarer. Fair enough. I hadn't noticed the SHORT_SYMLINK_LEN case when I wrote this. That does change things somewhat, but still for a 160 byte symlink, we have 5 cachelines of data and 59 cachelines of zeroes. > BTW, do we need to migrate the owner_2 flag in folio_migrate_flags()? > If so, I am not quite sure it is worth changing the hotpath to > accommodate this. It already happens, it's just camouflaged. owner_2 is the same bit as mappedtodisk. ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-12-28 4:30 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-12-24 9:40 [PATCH] mm/shmem: fix uninitialized folio in shmem_symlink Barry Song 2025-12-24 17:01 ` Matthew Wilcox 2025-12-25 4:04 ` Barry Song 2025-12-25 10:08 ` Baolin Wang 2025-12-28 4:29 ` Matthew Wilcox
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox