History

mm/filemap.c: fix NULL pointer in page_cache_tree_insert()

f2fs specifies the __GFP_ZERO flag for allocating some of its pages. Unfortunately, the page cache also uses the mapping's GFP flags for allocating radix tree nodes. It always masked off the __GFP_HIGHMEM flag, and masks off __GFP_ZERO in some paths, but not all. That causes radix tree nodes to be allocated with a NULL list_head, which causes backtraces like: __list_del_entry+0x30/0xd0 list_lru_del+0xac/0x1ac page_cache_tree_insert+0xd8/0x110 The __GFP_DMA and __GFP_DMA32 flags would also be able to sneak through if they are ever used. Fix them all by using GFP_RECLAIM_MASK at the innermost location, and remove it from earlier in the callchain.

Matthew Wilcox committed 8 years ago

Commit abc1be11 parent c892fd81 file · +4 −5Browse files

Unified · Split

mm/filemap.c+4−5
@@ -786,7 +786,7 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask) · 785 unmodified lines
786 VM_BUG_ON_PAGE(!PageLocked(new), new);786 VM_BUG_ON_PAGE(!PageLocked(new), new);
787 VM_BUG_ON_PAGE(new->mapping, new);787 VM_BUG_ON_PAGE(new->mapping, new);
788 788
789 error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);789 error = radix_tree_preload(gfp_mask & GFP_RECLAIM_MASK);
790 if (!error) {790 if (!error) {
791 struct address_space *mapping = old->mapping;791 struct address_space *mapping = old->mapping;
792 void (*freepage)(struct page *);792 void (*freepage)(struct page *);
@@ -842,7 +842,7 @@ static int __add_to_page_cache_locked(struct page *page, · 49 unmodified lines
842 return error;842 return error;
843 }843 }
844 844
845 error = radix_tree_maybe_preload(gfp_mask & ~__GFP_HIGHMEM);845 error = radix_tree_maybe_preload(gfp_mask & GFP_RECLAIM_MASK);
846 if (error) {846 if (error) {
847 if (!huge)847 if (!huge)
848 mem_cgroup_cancel_charge(page, memcg, false);848 mem_cgroup_cancel_charge(page, memcg, false);
@@ -1585,8 +1585,7 @@ no_page: · 736 unmodified lines
1585 if (fgp_flags & FGP_ACCESSED)1585 if (fgp_flags & FGP_ACCESSED)
1586 __SetPageReferenced(page);1586 __SetPageReferenced(page);
1587 1587
1588 err = add_to_page_cache_lru(page, mapping, offset,1588 err = add_to_page_cache_lru(page, mapping, offset, gfp_mask);
1589 gfp_mask & GFP_RECLAIM_MASK);
1590 if (unlikely(err)) {1589 if (unlikely(err)) {
1591 put_page(page);1590 put_page(page);
1592 page = NULL;1591 page = NULL;
@@ -2387,7 +2386,7 @@ static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask) · 794 unmodified lines
2387 if (!page)2386 if (!page)
2388 return -ENOMEM;2387 return -ENOMEM;
2389 2388
2390 ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask & GFP_KERNEL);2389 ret = add_to_page_cache_lru(page, mapping, offset, gfp_mask);
2391 if (ret == 0)2390 if (ret == 0)
2392 ret = mapping->a_ops->readpage(file, page);2391 ret = mapping->a_ops->readpage(file, page);
2393 else if (ret == -EEXIST)2392 else if (ret == -EEXIST)