Potential Linux Crash: WARNING in __getblk_slow in Linux kernel v6.13-rc5
From: Matthew Wilcox
Date: Thu Mar 06 2025 - 00:11:05 EST
On Thu, Mar 06, 2025 at 10:54:13AM +0800, Luka wrote:
> Dear Linux Kernel Experts,
>
> Hello!
>
> I am a security researcher focused on testing Linux kernel
> vulnerabilities. Recently, while testing the v6.13-rc5 Linux kernel,
> we encountered a crash related to the mm kernel module. We have
> successfully captured the call trace information for this crash.
>
> Unfortunately, we have not been able to reproduce the issue in our
> local environment, so we are unable to provide a PoC (Proof of
> Concept) at this time.
>
> We fully understand the complexity and importance of Linux kernel
> maintenance, and we would like to share this finding with you for
> further analysis and confirmation of the root cause. Below is a
> summary of the relevant information:
You're a "security researcher" ... but you're not even going to do a
cursory look at the code to figure out what's going on?
if (unlikely(nofail)) {
...
WARN_ON_ONCE(current->flags & PF_MEMALLOC);
^^^ that's the line which triggered the warning. So it's not a
problem in the memory allocator at all, it's the memory allocator
reporting that someone's asked it to satisfy some impossible
constraints.
> alloc_pages_mpol_noprof+0xda/0x300 mm/mempolicy.c:2269
> folio_alloc_noprof+0x1e/0x70 mm/mempolicy.c:2355
> filemap_alloc_folio_noprof+0x2b2/0x2f0 mm/filemap.c:1009
> __filemap_get_folio+0x16d/0x3d0 mm/filemap.c:1951
> grow_dev_folio fs/buffer.c:1039 [inline]
> grow_buffers fs/buffer.c:1105 [inline]
> __getblk_slow+0x138/0x430 fs/buffer.c:1131
> bdev_getblk fs/buffer.c:1431 [inline]
> __bread_gfp+0xea/0x2c0 fs/buffer.c:1485
__bread_gfp is who sets GFP_NOFAIL.
> sb_bread include/linux/buffer_head.h:346 [inline]
> fat12_ent_bread+0x231/0x3f0 fs/fat/fatent.c:86
> fat_ent_read+0x624/0xaa0 fs/fat/fatent.c:368
> fat_free_clusters+0x19c/0x860 fs/fat/fatent.c:568
> fat_free.isra.0+0x377/0x850 fs/fat/file.c:376
> fat_truncate_blocks+0x10d/0x190 fs/fat/file.c:394
> fat_free_eofblocks fs/fat/inode.c:633 [inline]
> fat_evict_inode+0x1b1/0x260 fs/fat/inode.c:658
> evict+0x337/0x7c0 fs/inode.c:796
> dispose_list fs/inode.c:845 [inline]
> prune_icache_sb+0x189/0x290 fs/inode.c:1033
> super_cache_scan+0x33d/0x510 fs/super.c:223
> do_shrink_slab mm/shrinker.c:437 [inline]
> shrink_slab+0x43e/0x930 mm/shrinker.c:664
> shrink_node_memcgs mm/vmscan.c:5931 [inline]
> shrink_node+0x4dd/0x15c0 mm/vmscan.c:5970
> shrink_zones mm/vmscan.c:6215 [inline]
> do_try_to_free_pages+0x284/0x1160 mm/vmscan.c:6277
> try_to_free_pages+0x1ee/0x3e0 mm/vmscan.c:6527
> __perform_reclaim mm/page_alloc.c:3929 [inline]
And __perform_reclaim() is where PF_MEMALLOC gets set.
> __alloc_pages_direct_reclaim mm/page_alloc.c:3951 [inline]
> __alloc_pages_slowpath mm/page_alloc.c:4382 [inline]
> __alloc_pages_noprof+0xa48/0x2040 mm/page_alloc.c:4766
> alloc_pages_mpol_noprof+0xda/0x300 mm/mempolicy.c:2269
> pagetable_alloc_noprof include/linux/mm.h:2899 [inline]
> __pte_alloc_one_noprof include/asm-generic/pgalloc.h:70 [inline]
> pte_alloc_one+0x20/0x1b0 arch/x86/mm/pgtable.c:33
> do_fault_around mm/memory.c:5274 [inline]
> do_read_fault mm/memory.c:5313 [inline]
> do_fault mm/memory.c:5456 [inline]
> do_pte_missing mm/memory.c:3979 [inline]
> handle_pte_fault mm/memory.c:5801 [inline]
> __handle_mm_fault+0x15b9/0x2380 mm/memory.c:5944
> handle_mm_fault+0x1c6/0x4c0 mm/memory.c:6112
> faultin_page mm/gup.c:1196 [inline]
> __get_user_pages+0x421/0x2550 mm/gup.c:1494
> populate_vma_page_range+0x16b/0x200 mm/gup.c:1932
> __mm_populate+0x1c2/0x360 mm/gup.c:2035
> mm_populate include/linux/mm.h:3396 [inline]
> vm_mmap_pgoff+0x25d/0x2f0 mm/util.c:585
> ksys_mmap_pgoff+0x5a/0x480 mm/mmap.c:542
Now, I'm not sure how best to solve this. Should FAT decline to read
entries if it's called from reclaim? I know XFS goes to some trouble to
not do that kind of thing. Or should buffer head allocation do
something to access the emergency reserves?