Skip to content

Commit f3a14ce

Browse files
JoonsooKimtorvalds
authored andcommitted
mm/page_owner: fix possible access violation
When I tested my new patches, I found that page pointer which is used for setting page_owner information is changed. This is because page pointer is used to set new migratetype in loop. After this work, page pointer could be out of bound. If this wrong pointer is used for page_owner, access violation happens. Below is error message that I got. BUG: unable to handle kernel paging request at 0000000000b00018 IP: [<ffffffff81025f30>] save_stack_address+0x30/0x40 PGD 1af2d067 PUD 166e0067 PMD 0 Oops: 0002 [#1] SMP ...snip... Call Trace: print_context_stack+0xcf/0x100 dump_trace+0x15f/0x320 save_stack_trace+0x2f/0x50 __set_page_owner+0x46/0x70 __isolate_free_page+0x1f7/0x210 split_free_page+0x21/0xb0 isolate_freepages_block+0x1e2/0x410 compaction_alloc+0x22d/0x2d0 migrate_pages+0x289/0x8b0 compact_zone+0x409/0x880 compact_zone_order+0x6d/0x90 try_to_compact_pages+0x110/0x210 __alloc_pages_direct_compact+0x3d/0xe6 __alloc_pages_nodemask+0x6cd/0x9a0 alloc_pages_current+0x91/0x100 runtest_store+0x296/0xa50 simple_attr_write+0xbd/0xe0 __vfs_write+0x28/0xf0 vfs_write+0xa9/0x1b0 SyS_write+0x46/0xb0 system_call_fastpath+0x16/0x75 This patch fixes this error by moving up set_page_owner(). Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com> Cc: Mel Gorman <mgorman@suse.de> Cc: Vlastimil Babka <vbabka@suse.cz> Acked-by: Minchan Kim <minchan@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent a2673b6 commit f3a14ce

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

mm/page_alloc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1994,6 +1994,8 @@ int __isolate_free_page(struct page *page, unsigned int order)
19941994
zone->free_area[order].nr_free--;
19951995
rmv_page_order(page);
19961996

1997+
set_page_owner(page, order, 0);
1998+
19971999
/* Set the pageblock if the isolated page is at least a pageblock */
19982000
if (order >= pageblock_order - 1) {
19992001
struct page *endpage = page + (1 << order) - 1;
@@ -2005,7 +2007,7 @@ int __isolate_free_page(struct page *page, unsigned int order)
20052007
}
20062008
}
20072009

2008-
set_page_owner(page, order, 0);
2010+
20092011
return 1UL << order;
20102012
}
20112013

0 commit comments

Comments
 (0)