2019-03-12 16:06:10

by zhong jiang

[permalink] [raw]
Subject: [Qestion] Hit a WARN_ON_ONCE in try_to_unmap_one when runing syzkaller

Hi,

I hit the following issue when running syzkaller in arm64. It is hardly to reproduce the issue by the attached log.

[ 206.633857] Injecting memory failure for pfn 0x38c7e0 at process virtual address 0x201e0000
[ 206.766875] WARNING: CPU: 1 PID: 738 at mm/rmap.c:1571 try_to_unmap_one+0x1004/0x17d8
[ 206.768476] Kernel panic - not syncing: panic_on_warn set ...
[ 206.768476]
[ 206.769981] CPU: 1 PID: 738 Comm: syz-executor.0 Not tainted 4.19.27 #9
[ 206.771510] Hardware name: linux,dummy-virt (DT)
[ 206.772673] Call trace:
[ 206.773230] dump_backtrace+0x0/0x3c0
[ 206.774021] show_stack+0x28/0x38
[ 206.774761] dump_stack+0x120/0x188
[ 206.775483] panic+0x21c/0x48c
[ 206.776152] __warn+0x280/0x2cc
[ 206.776838] report_bug+0x1c8/0x2c8
[ 206.777612] bug_handler+0x8c/0x178
[ 206.778394] call_break_hook+0x238/0x338
[ 206.779410] brk_handler+0x3c/0xe8
[ 206.780186] do_debug_exception+0x12c/0x378
[ 206.781059] el1_dbg+0x18/0x84
[ 206.781732] try_to_unmap_one+0x1004/0x17d8
[ 206.782624] rmap_walk_anon+0x2b4/0x7a8
[ 206.783454] rmap_walk+0xfc/0x180
[ 206.784165] try_to_unmap+0x290/0x360
[ 206.784946] hwpoison_user_mappings.isra.5+0x5ec/0x1478
[ 206.786045] memory_failure+0x8c0/0xf00
[ 206.786872] __arm64_sys_madvise+0xc90/0x1278
[ 206.787786] el0_svc_handler+0x13c/0x308
[ 206.788626] el0_svc+0x8/0xc
[ 206.791030] SMP: stopping secondary CPUs
[ 206.792168] Dumping ftrace buffer:
[ 206.796278] (ftrace buffer empty)
[ 206.797065] Kernel Offset: disabled
[ 206.797811] CPU features: 0x0,a1806000
[ 206.798625] Memory Limit: none
[ 206.800300] Rebooting in 86400 seconds..

Minchan has changed the conditon check from BUG_ON to WARN_ON_ONCE in try_to_unmap_one.
However, It is still an abnormal condition when PageSwapBacked is not equal to PageSwapCache.

But Is there any case it will meet the conditon in the mainline.

It is assumed that PageSwapBacked(page) is true in the anonymous page, This is to say, PageSwapcache
is false. however, That is impossible because we will update the pte for hwpoison entry.

Because page is locked , Its page flags should not be changed except for PageSwapBacked.

Thanks,
zhong jiang


Attachments:
reproduce.txt (92.62 kB)

2019-03-14 06:31:42

by Naoya Horiguchi

[permalink] [raw]
Subject: Re: [Qestion] Hit a WARN_ON_ONCE in try_to_unmap_one when runing syzkaller

Hi,

On Wed, Mar 13, 2019 at 12:03:20AM +0800, zhong jiang wrote:
...
>
> Minchan has changed the conditon check from BUG_ON to WARN_ON_ONCE in try_to_unmap_one.
> However, It is still an abnormal condition when PageSwapBacked is not equal to PageSwapCache.
>
> But Is there any case it will meet the conditon in the mainline.
>
> It is assumed that PageSwapBacked(page) is true in the anonymous page, This is to say, PageSwapcache
> is false. however, That is impossible because we will update the pte for hwpoison entry.
>
> Because page is locked , Its page flags should not be changed except for PageSwapBacked

try_to_unmap_one() from hwpoison_user_mappings() could reach the
WARN_ON_ONCE() only if TTU_IGNORE_HWPOISON is set, because PageHWPoison()
is set at the beginning of memory_failure().

Clearing TTU_IGNORE_HWPOISON might happen on the following two paths:

static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
int flags, struct page **hpagep)
{
...

if (PageSwapCache(p)) {
pr_err("Memory failure: %#lx: keeping poisoned page in swap cache\n",
pfn);
ttu |= TTU_IGNORE_HWPOISON;
}
...

mapping = page_mapping(hpage);
if (!(flags & MF_MUST_KILL) && !PageDirty(hpage) && mapping &&
mapping_cap_writeback_dirty(mapping)) {
if (page_mkclean(hpage)) {
SetPageDirty(hpage);
} else {
kill = 0;
ttu |= TTU_IGNORE_HWPOISON;
pr_info("Memory failure: %#lx: corrupted page was clean: dropped without side effects\n",
pfn);
}
}
...

unmap_success = try_to_unmap(hpage, ttu);
...

So either of the above "ttu |= TTU_IGNORE_HWPOISON" should be executed.
I'm not sure which one, but both paths show printk messages, so if you
could have kernel message log, that might help ...

Thanks,
Naoya Horiguchi

2019-03-14 07:57:17

by zhong jiang

[permalink] [raw]
Subject: Re: [Qestion] Hit a WARN_ON_ONCE in try_to_unmap_one when runing syzkaller

On 2019/3/14 14:27, Naoya Horiguchi wrote:
> Hi,
>
> On Wed, Mar 13, 2019 at 12:03:20AM +0800, zhong jiang wrote:
> ...
>> Minchan has changed the conditon check from BUG_ON to WARN_ON_ONCE in try_to_unmap_one.
>> However, It is still an abnormal condition when PageSwapBacked is not equal to PageSwapCache.
>>
>> But Is there any case it will meet the conditon in the mainline.
>>
>> It is assumed that PageSwapBacked(page) is true in the anonymous page, This is to say, PageSwapcache
>> is false. however, That is impossible because we will update the pte for hwpoison entry.
>>
>> Because page is locked , Its page flags should not be changed except for PageSwapBacked
> try_to_unmap_one() from hwpoison_user_mappings() could reach the
> WARN_ON_ONCE() only if TTU_IGNORE_HWPOISON is set, because PageHWPoison()
> is set at the beginning of memory_failure().
>
> Clearing TTU_IGNORE_HWPOISON might happen on the following two paths:
>
> static bool hwpoison_user_mappings(struct page *p, unsigned long pfn,
> int flags, struct page **hpagep)
> {
> ...
>
> if (PageSwapCache(p)) {
> pr_err("Memory failure: %#lx: keeping poisoned page in swap cache\n",
> pfn);
> ttu |= TTU_IGNORE_HWPOISON;
> }
> ...
>
> mapping = page_mapping(hpage);
> if (!(flags & MF_MUST_KILL) && !PageDirty(hpage) && mapping &&
> mapping_cap_writeback_dirty(mapping)) {
> if (page_mkclean(hpage)) {
> SetPageDirty(hpage);
> } else {
> kill = 0;
> ttu |= TTU_IGNORE_HWPOISON;
> pr_info("Memory failure: %#lx: corrupted page was clean: dropped without side effects\n",
> pfn);
> }
> }
> ...
>
> unmap_success = try_to_unmap(hpage, ttu);
> ...
>
> So either of the above "ttu |= TTU_IGNORE_HWPOISON" should be executed.
> I'm not sure which one, but both paths show printk messages, so if you
> could have kernel message log, that might help ...
Thank you for your response.

Unfortunately, I lost the printk log. I was looking for it before and support us for further analysis.

It's very weird to get there. Assume that TTU_IGNORE_HWPOSISON is set. There is the two case.

First, PageSwapCache is set and page has been locked. Theoretically WARN_ON_ONCE should not be triggered.
Second, We should assume the page belongs to file page.:-(

I will go on reproducing the issue and get the printk message log.

Thanks
zhong jiang
> Thanks,
> Naoya Horiguchi
>
> .
>