linux-stable/mm
Gang Li d8d9559c46 shmem: fix a race between shmem_unused_huge_shrink and shmem_evict_inode
commit 62c9827cbb upstream.

Fix a data race in commit 779750d20b ("shmem: split huge pages beyond
i_size under memory pressure").

Here are call traces causing race:

   Call Trace 1:
     shmem_unused_huge_shrink+0x3ae/0x410
     ? __list_lru_walk_one.isra.5+0x33/0x160
     super_cache_scan+0x17c/0x190
     shrink_slab.part.55+0x1ef/0x3f0
     shrink_node+0x10e/0x330
     kswapd+0x380/0x740
     kthread+0xfc/0x130
     ? mem_cgroup_shrink_node+0x170/0x170
     ? kthread_create_on_node+0x70/0x70
     ret_from_fork+0x1f/0x30

   Call Trace 2:
     shmem_evict_inode+0xd8/0x190
     evict+0xbe/0x1c0
     do_unlinkat+0x137/0x330
     do_syscall_64+0x76/0x120
     entry_SYSCALL_64_after_hwframe+0x3d/0xa2

A simple explanation:

Image there are 3 items in the local list (@list).  In the first
traversal, A is not deleted from @list.

  1)    A->B->C
        ^
        |
        pos (leave)

In the second traversal, B is deleted from @list.  Concurrently, A is
deleted from @list through shmem_evict_inode() since last reference
counter of inode is dropped by other thread.  Then the @list is corrupted.

  2)    A->B->C
        ^  ^
        |  |
     evict pos (drop)

We should make sure the inode is either on the global list or deleted from
any local list before iput().

Fixed by moving inodes back to global list before we put them.

[akpm@linux-foundation.org: coding style fixes]

Link: https://lkml.kernel.org/r/20211125064502.99983-1-ligang.bdlg@bytedance.com
Fixes: 779750d20b ("shmem: split huge pages beyond i_size under memory pressure")
Signed-off-by: Gang Li <ligang.bdlg@bytedance.com>
Reviewed-by: Muchun Song <songmuchun@bytedance.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-01-27 09:00:48 +01:00
..
kasan
backing-dev.c mm: bdi: initialize bdi_min_ratio when bdi is unregistered 2021-12-14 10:16:54 +01:00
balloon_compaction.c
bootmem.c
cleancache.c
cma.c mm/cma.c: fail if fixed declaration can't be honored 2019-08-06 19:05:23 +02:00
cma.h
cma_debug.c mm/cma_debug.c: fix the break condition in cma_maxchunk_get() 2019-06-15 11:54:51 +02:00
compaction.c mm/compaction.c: clear total_{migrate,free}_scanned before scanning a new zone 2019-10-05 12:48:13 +02:00
debug.c
debug_page_ref.c
dmapool.c
early_ioremap.c
fadvise.c
failslab.c
filemap.c mm/filemap.c: clear page error before actual read 2020-10-01 13:12:40 +02:00
frame_vector.c
frontswap.c
gup.c gup: document and work around "COW can break either way" issue 2021-04-28 12:08:42 +02:00
highmem.c
hmm.c
huge_memory.c mm/huge_memory.c: don't discard hugepage if other processes are mapping it 2021-07-20 16:17:41 +02:00
hugetlb.c hugetlb: take PMD sharing into account when flushing tlb/caches 2021-12-08 08:46:53 +01:00
hugetlb_cgroup.c mm: hugetlb: switch to css_tryget() in hugetlb_cgroup_charge_cgroup() 2019-11-20 17:59:33 +01:00
hwpoison-inject.c
init-mm.c
internal.h mm/thp: fix vma_address() if virtual address below file offset 2021-07-11 12:48:10 +02:00
interval_tree.c
Kconfig mm/hmm: select mmu notifier when selecting HMM 2019-06-15 11:54:51 +02:00
Kconfig.debug
khugepaged.c khugepaged: fix wrong result value for trace_mm_collapse_huge_page_isolate() 2021-05-22 10:57:39 +02:00
kmemleak-test.c
kmemleak.c mm/kmemleak.c: make cond_resched() rate-limiting more efficient 2021-09-22 11:45:16 +02:00
ksm.c ksm: fix potential missing rmap_item for stable_node 2021-05-22 10:57:39 +02:00
list_lru.c mm/list_lru.c: fix memory leak in __memcg_init_list_lru_node 2019-06-19 08:20:54 +02:00
maccess.c uaccess: Add non-pagefault user-space write function 2020-09-09 19:03:11 +02:00
madvise.c
Makefile
memblock.c memblock: do not start bottom-up allocations with kernel_end 2021-02-23 14:00:32 +01:00
memcontrol.c mm: writeback: use exact memcg dirty counts 2021-04-07 12:47:03 +02:00
memory-failure.c mm/memory-failure: make sure wait for page writeback in memory_failure 2021-06-30 08:48:48 -04:00
memory.c hugetlbfs: flush TLBs correctly after huge_pmd_unshare 2021-12-08 08:46:52 +01:00
memory_hotplug.c mm/memory_hotplug: use "unsigned long" for PFN in zone_for_pfn_range() 2021-09-22 11:45:34 +02:00
mempolicy.c mm: mempolicy: fix potential pte_unmap_unlock pte error 2020-11-18 18:27:52 +01:00
mempool.c
memtest.c
migrate.c mm/migrate.c: add missing flush_dcache_page for non-mapped page migrate 2019-04-03 06:25:20 +02:00
mincore.c mm/mincore.c: make mincore() more conservative 2019-05-21 18:50:16 +02:00
mlock.c mm/mlock.c: change count_mm_mlocked_page_nr return type 2019-07-10 09:54:36 +02:00
mm_init.c
mmap.c mm/mmap.c: initialize align_offset explicitly for vm_unmapped_area 2020-10-01 13:12:41 +02:00
mmu_context.c
mmu_notifier.c mm/mmu_notifier: use hlist_add_head_rcu() 2019-07-31 07:28:56 +02:00
mmzone.c
mprotect.c mm, numa: fix bad pmd by atomically check for pmd_trans_huge when marking page tables prot_numa 2020-03-11 18:03:02 +01:00
mremap.c mm: Fix mremap not considering huge pmd devmap 2020-06-11 09:22:57 +02:00
msync.c
nobootmem.c
nommu.c x86/mm: split vmalloc_sync_all() 2020-04-02 16:34:20 +02:00
oom_kill.c mm, oom: do not trigger out_of_memory from the #PF 2021-11-26 11:40:37 +01:00
page-writeback.c mm/page-writeback.c: avoid potential division by zero in wb_min_max_ratio() 2020-01-23 08:20:32 +01:00
page_alloc.c mm/page_alloc: speed up the iteration of max_order 2021-09-22 11:45:16 +02:00
page_counter.c
page_ext.c mm/page_ext.c: fix an imbalance with kmemleak 2019-04-05 22:31:27 +02:00
page_idle.c mm/page_idle.c: fix oops because end_pfn is larger than max_pfn 2019-07-03 13:15:59 +02:00
page_io.c swap: fix swapfile read/write offset 2021-03-07 11:27:46 +01:00
page_isolation.c
page_owner.c mm/page_owner.c: remove drain_all_pages from init_early_allocated_pages 2020-07-31 16:44:45 +02:00
page_poison.c page_poison: play nicely with KASAN 2019-04-05 22:31:28 +02:00
page_vma_mapped.c mm/thp: another PVMW_SYNC fix in page_vma_mapped_walk() 2021-07-11 12:48:12 +02:00
pagewalk.c mm: pagewalk: fix termination condition in walk_pte_range() 2020-10-01 13:12:32 +02:00
percpu-internal.h
percpu-km.c
percpu-stats.c
percpu-vm.c
percpu.c percpu: fix first chunk size calculation for populated bitmap 2020-09-23 10:46:36 +02:00
pgtable-generic.c
process_vm_access.c
quicklist.c
readahead.c
rmap.c mm/thp: fix page_address_in_vma() on file THP tails 2021-07-11 12:48:10 +02:00
rodata_test.c
shmem.c shmem: fix a race between shmem_unused_huge_shrink and shmem_evict_inode 2022-01-27 09:00:48 +01:00
slab.c mm/slab.c: fix an infinite loop in leaks_show() 2019-06-15 11:54:51 +02:00
slab.h mm: kmemleak: slob: respect SLAB_NOLEAKTRACE flag 2021-11-26 11:40:40 +01:00
slab_common.c mm/slab: use memzero_explicit() in kzfree() 2020-06-30 15:38:08 -04:00
slob.c
slub.c mm/slub.c: include swab.h 2021-06-30 08:48:54 -04:00
sparse-vmemmap.c
sparse.c
swap.c
swap_cgroup.c
swap_slots.c
swap_state.c mm/swap_state: fix a data race in swapin_nr_pages 2020-10-01 13:12:46 +02:00
swapfile.c swap: fix swapfile read/write offset 2021-03-07 11:27:46 +01:00
truncate.c
usercopy.c usercopy: Avoid HIGHMEM pfn warning 2019-10-11 18:18:34 +02:00
userfaultfd.c hugetlbfs: hugetlb_fault_mutex_hash() cleanup 2021-06-03 08:36:25 +02:00
util.c mm: add kvfree_sensitive() for freeing sensitive data objects 2020-06-20 10:24:59 +02:00
vmacache.c
vmalloc.c mm/vmalloc.c: don't dereference possible NULL pointer in __vunmap() 2020-06-03 08:18:11 +02:00
vmpressure.c
vmscan.c mm: memcg: make sure memory.events is uptodate when waking pollers 2021-04-07 12:47:03 +02:00
vmstat.c mm, vmstat: drop zone->lock in /proc/pagetypeinfo 2021-06-03 08:36:10 +02:00
workingset.c
z3fold.c
zbud.c
zpool.c
zsmalloc.c mm/zsmalloc.c: close race window between zs_pool_dec_isolated() and zs_unregister_migration() 2021-11-26 11:40:36 +01:00
zswap.c