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
786786 VM_BUG_ON_PAGE(!PageLocked(new), new);
787787 VM_BUG_ON_PAGE(new->mapping, new);
788788
789− error = radix_tree_preload(gfp_mask & ~__GFP_HIGHMEM);
789+ error = radix_tree_preload(gfp_mask & GFP_RECLAIM_MASK);
790790 if (!error) {
791791 struct address_space *mapping = old->mapping;
792792 void (*freepage)(struct page *);
@@ -842,7 +842,7 @@ static int __add_to_page_cache_locked(struct page *page, · 49 unmodified lines
842842 return error;
843843 }
844844
845− error = radix_tree_maybe_preload(gfp_mask & ~__GFP_HIGHMEM);
845+ error = radix_tree_maybe_preload(gfp_mask & GFP_RECLAIM_MASK);
846846 if (error) {
847847 if (!huge)
848848 mem_cgroup_cancel_charge(page, memcg, false);
@@ -1585,8 +1585,7 @@ no_page: · 736 unmodified lines
15851585 if (fgp_flags & FGP_ACCESSED)
15861586 __SetPageReferenced(page);
15871587
1588− err = add_to_page_cache_lru(page, mapping, offset,
1589− gfp_mask & GFP_RECLAIM_MASK);
1588+ err = add_to_page_cache_lru(page, mapping, offset, gfp_mask);
15901589 if (unlikely(err)) {
15911590 put_page(page);
15921591 page = NULL;
@@ -2387,7 +2386,7 @@ static int page_cache_read(struct file *file, pgoff_t offset, gfp_t gfp_mask) · 794 unmodified lines
23872386 if (!page)
23882387 return -ENOMEM;
23892388
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);
23912390 if (ret == 0)
23922391 ret = mapping->a_ops->readpage(file, page);
23932392 else if (ret == -EEXIST)