LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* kernel BUG at include/linux/mm.h:LINE!
@ 2018-05-01 8:31 syzbot
2018-05-01 10:10 ` Tetsuo Handa
2018-05-03 21:04 ` kernel BUG at include/linux/mm.h:LINE! syzbot
0 siblings, 2 replies; 9+ messages in thread
From: syzbot @ 2018-05-01 8:31 UTC (permalink / raw)
To: akpm, bhe, dyoung, hpa, kirill.shutemov, linux-kernel, mingo,
prudo, syzkaller-bugs, takahiro.akashi, tglx, thomas.lendacky,
x86, xlpang
Hello,
syzbot found the following crash on:
HEAD commit: 6da6c0db5316 Linux v4.17-rc3
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?id=5229040734568448
kernel config:
https://syzkaller.appspot.com/x/.config?id=6493557782959164711
dashboard link: https://syzkaller.appspot.com/bug?extid=d96f60296ef613fe1d69
compiler: gcc (GCC) 8.0.1 20180413 (experimental)
Unfortunately, I don't have any reproducer for this crash yet.
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+d96f60296ef613fe1d69@syzkaller.appspotmail.com
flags: 0x2fffc0000000000()
raw: 02fffc0000000000 0000000000000000 0000000000000000 00000000ffffffff
raw: ffffea00071786e0 ffff8801daf2fdd8 0000000000000000 0000000000000000
page dumped because: VM_BUG_ON_PAGE(page_ref_count(page) == 0)
------------[ cut here ]------------
kernel BUG at include/linux/mm.h:492!
invalid opcode: 0000 [#1] SMP KASAN
Dumping ftrace buffer:
(ftrace buffer empty)
Modules linked in:
CPU: 1 PID: 10012 Comm: syz-executor1 Not tainted 4.17.0-rc3+ #25
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
RIP: 0010:put_page_testzero include/linux/mm.h:492 [inline]
RIP: 0010:__free_pages+0x14f/0x180 mm/page_alloc.c:4427
RSP: 0018:ffff8801b881fc08 EFLAGS: 00010203
RAX: 0000000000000000 RBX: 1ffff10037103f82 RCX: 0000000000000000
RDX: 0000000000040000 RSI: ffffffff81a5b455 RDI: ffffed0037103f70
RBP: ffff8801b881fc98 R08: ffff8801b0c9a080 R09: 0000000000000006
R10: ffff8801b0c9a080 R11: 0000000000000000 R12: ffffea00072e24c0
R13: 1ffff10037103f86 R14: ffff8801b881fc70 R15: ffffea00072e24dc
FS: 00007f2e2794c700(0000) GS:ffff8801daf00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000020000000 CR3: 00000001ae61b000 CR4: 00000000001406e0
DR0: 0000000020000000 DR1: 0000000020000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000600
Call Trace:
free_pages+0x50/0x90 mm/page_alloc.c:4441
free_transition_pgtable+0x68/0xf0 arch/x86/kernel/machine_kexec_64.c:42
machine_kexec_cleanup+0x9/0x10 arch/x86/kernel/machine_kexec_64.c:268
kimage_free+0x1f2/0x270 kernel/kexec_core.c:639
do_kexec_load+0x53a/0x790 kernel/kexec.c:170
__do_sys_kexec_load kernel/kexec.c:243 [inline]
__se_sys_kexec_load kernel/kexec.c:218 [inline]
__x64_sys_kexec_load+0x1bf/0x230 kernel/kexec.c:218
do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x455979
RSP: 002b:00007f2e2794bc68 EFLAGS: 00000246 ORIG_RAX: 00000000000000f6
RAX: ffffffffffffffda RBX: 00007f2e2794c6d4 RCX: 0000000000455979
RDX: 0000000020000000 RSI: 0000000000000001 RDI: 0000000000000000
RBP: 000000000072bea0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000013
R13: 0000000000000403 R14: 00000000006fa0e8 R15: 000000000000000a
Code: 68 5b 41 5c 41 5d 41 5e 41 5f 5d c3 8b b5 74 ff ff ff 4c 89 e7 e8 02
87 ff ff eb c6 48 c7 c6 00 66 d0 87 4c 89 e7 e8 81 7a 0d 00 <0f> 0b 4c 89
ef 89 85 70 ff ff ff e8 51 7b 1d 00 8b 85 70 ff ff
RIP: put_page_testzero include/linux/mm.h:492 [inline] RSP: ffff8801b881fc08
RIP: __free_pages+0x14f/0x180 mm/page_alloc.c:4427 RSP: ffff8801b881fc08
---[ end trace f3320966708ec92c ]---
---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.
syzbot will keep track of this bug report.
If you forgot to add the Reported-by tag, once the fix for this bug is
merged
into any tree, please reply to this email with:
#syz fix: exact-commit-title
To mark this as a duplicate of another syzbot report, please reply with:
#syz dup: exact-subject-of-another-report
If it's a one-off invalid bug report, please reply with:
#syz invalid
Note: if the crash happens again, it will cause creation of a new bug
report.
Note: all commands must start from beginning of the line in the email body.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: kernel BUG at include/linux/mm.h:LINE!
2018-05-01 8:31 kernel BUG at include/linux/mm.h:LINE! syzbot
@ 2018-05-01 10:10 ` Tetsuo Handa
2018-05-04 0:32 ` Baoquan He
2018-05-03 21:04 ` kernel BUG at include/linux/mm.h:LINE! syzbot
1 sibling, 1 reply; 9+ messages in thread
From: Tetsuo Handa @ 2018-05-01 10:10 UTC (permalink / raw)
To: syzbot, kirill.shutemov, linux-kernel, syzkaller-bugs,
Huang Ying, H. Peter Anvin, Ingo Molnar
Cc: akpm, bhe, dyoung, mingo, prudo, takahiro.akashi, tglx,
thomas.lendacky, x86, xlpang
>From d54b2acf63191eba3d5052bf34fe6d26e3580ac2 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Tue, 1 May 2018 15:36:52 +0900
Subject: [PATCH] x86/kexec: avoid double free_page() upon do_kexec_load()
failure.
syzbot is reporting crashes after memory allocation failure inside
do_kexec_load() [1]. This is because free_transition_pgtable() is called
by both init_transition_pgtable() and machine_kexec_cleanup() when memory
allocation failed inside init_transition_pgtable().
Regarding 32bit code, machine_kexec_free_page_tables() is called by both
machine_kexec_alloc_page_tables() and machine_kexec_cleanup() when memory
allocation failed inside machine_kexec_alloc_page_tables().
Fix this by explicitly setting NULL after free_page().
[1] https://syzkaller.appspot.com/bug?id=91e52396168cf2bdd572fe1e1bc0bc645c1c6b40
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reported-by: syzbot <syzbot+d96f60296ef613fe1d69@syzkaller.appspotmail.com>
Fixes: f5deb79679af6eb4 ("x86: kexec: Use one page table in x86_64 machine_kexec")
Fixes: 92be3d6bdf2cb349 ("kexec/i386: allocate page table pages dynamically")
Cc: Huang Ying <ying.huang@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@elte.hu>
---
arch/x86/kernel/machine_kexec_32.c | 5 +++++
arch/x86/kernel/machine_kexec_64.c | 4 ++++
2 files changed, 9 insertions(+)
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 60cdec6..ceccfe4 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -57,12 +57,17 @@ static void load_segments(void)
static void machine_kexec_free_page_tables(struct kimage *image)
{
free_page((unsigned long)image->arch.pgd);
+ image->arch.pgd = NULL;
#ifdef CONFIG_X86_PAE
free_page((unsigned long)image->arch.pmd0);
+ image->arch.pmd0 = NULL;
free_page((unsigned long)image->arch.pmd1);
+ image->arch.pmd1 = NULL;
#endif
free_page((unsigned long)image->arch.pte0);
+ image->arch.pte0 = NULL;
free_page((unsigned long)image->arch.pte1);
+ image->arch.pte1 = NULL;
}
static int machine_kexec_alloc_page_tables(struct kimage *image)
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index a5e55d8..76aaee9 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -39,9 +39,13 @@
static void free_transition_pgtable(struct kimage *image)
{
free_page((unsigned long)image->arch.p4d);
+ image->arch.p4d = NULL;
free_page((unsigned long)image->arch.pud);
+ image->arch.pud = NULL;
free_page((unsigned long)image->arch.pmd);
+ image->arch.pmd = NULL;
free_page((unsigned long)image->arch.pte);
+ image->arch.pte = NULL;
}
static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
--
1.8.3.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: kernel BUG at include/linux/mm.h:LINE!
2018-05-01 8:31 kernel BUG at include/linux/mm.h:LINE! syzbot
2018-05-01 10:10 ` Tetsuo Handa
@ 2018-05-03 21:04 ` syzbot
2018-05-03 23:38 ` [PATCH v2] x86/kexec: avoid double free_page() upon do_kexec_load() failure Tetsuo Handa
1 sibling, 1 reply; 9+ messages in thread
From: syzbot @ 2018-05-03 21:04 UTC (permalink / raw)
To: akpm, bhe, dyoung, hpa, kirill.shutemov, linux-kernel, mingo,
mingo, penguin-kernel, prudo, syzkaller-bugs, takahiro.akashi,
tglx, thomas.lendacky, x86, xlpang, ying.huang
syzbot has found a reproducer for the following crash on:
HEAD commit: c15f6d8d4715 Merge tag 'dma-mapping-4.17-4' of git://git.i..
git tree: upstream
console output: https://syzkaller.appspot.com/x/log.txt?x=165343c7800000
kernel config: https://syzkaller.appspot.com/x/.config?x=5a1dc06635c10d27
dashboard link: https://syzkaller.appspot.com/bug?extid=d96f60296ef613fe1d69
compiler: gcc (GCC) 8.0.1 20180413 (experimental)
syzkaller repro:https://syzkaller.appspot.com/x/repro.syz?x=105a4437800000
IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+d96f60296ef613fe1d69@syzkaller.appspotmail.com
flags: 0x2fffc0000000000()
raw: 02fffc0000000000 0000000000000000 0000000000000000 00000000ffffffff
raw: ffffea0006b60aa0 ffff8801dae2fdd8 0000000000000000 0000000000000000
page dumped because: VM_BUG_ON_PAGE(page_ref_count(page) == 0)
------------[ cut here ]------------
kernel BUG at include/linux/mm.h:492!
invalid opcode: 0000 [#1] SMP KASAN
Dumping ftrace buffer:
(ftrace buffer empty)
Modules linked in:
CPU: 0 PID: 4524 Comm: syz-executor0 Not tainted 4.17.0-rc3+ #31
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
Google 01/01/2011
RIP: 0010:put_page_testzero include/linux/mm.h:492 [inline]
RIP: 0010:__free_pages+0x14f/0x180 mm/page_alloc.c:4427
RSP: 0018:ffff8801ad01fc08 EFLAGS: 00010203
RAX: 0000000000000000 RBX: 1ffff10035a03f82 RCX: 0000000000000000
RDX: 0000000000000000 RSI: ffffffff81a5b2e5 RDI: ffffed0035a03f70
RBP: ffff8801ad01fc98 R08: ffff8801ad09e740 R09: ffffed003b5c4fb0
R10: ffffed003b5c4fb0 R11: ffff8801dae27d87 R12: ffffea0006b6e740
R13: 1ffff10035a03f86 R14: ffff8801ad01fc70 R15: ffffea0006b6e75c
FS: 0000000002891940(0000) GS:ffff8801dae00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00000000004d9fc4 CR3: 00000001ad7ed000 CR4: 00000000001406f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
free_pages+0x50/0x90 mm/page_alloc.c:4441
free_transition_pgtable+0x68/0xf0 arch/x86/kernel/machine_kexec_64.c:42
machine_kexec_cleanup+0x9/0x10 arch/x86/kernel/machine_kexec_64.c:268
kimage_free+0x1f2/0x270 kernel/kexec_core.c:639
do_kexec_load+0x53a/0x790 kernel/kexec.c:170
__do_sys_kexec_load kernel/kexec.c:243 [inline]
__se_sys_kexec_load kernel/kexec.c:218 [inline]
__x64_sys_kexec_load+0x1bf/0x230 kernel/kexec.c:218
do_syscall_64+0x1b1/0x800 arch/x86/entry/common.c:287
entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x455979
RSP: 002b:00007ffdca50c2b8 EFLAGS: 00000246 ORIG_RAX: 00000000000000f6
RAX: ffffffffffffffda RBX: 0000000002891914 RCX: 0000000000455979
RDX: 00000000200001c0 RSI: 0000000000000001 RDI: 0000000000000000
RBP: 000000000072bea0 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000004
R13: 0000000000000403 R14: 00000000006fa0e8 R15: 0000000000000005
Code: 68 5b 41 5c 41 5d 41 5e 41 5f 5d c3 8b b5 74 ff ff ff 4c 89 e7 e8 02
87 ff ff eb c6 48 c7 c6 00 66 d0 87 4c 89 e7 e8 81 7a 0d 00 <0f> 0b 4c 89
ef 89 85 70 ff ff ff e8 51 7b 1d 00 8b 85 70 ff ff
RIP: put_page_testzero include/linux/mm.h:492 [inline] RSP: ffff8801ad01fc08
RIP: __free_pages+0x14f/0x180 mm/page_alloc.c:4427 RSP: ffff8801ad01fc08
---[ end trace dbb114ab9bd59585 ]---
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2] x86/kexec: avoid double free_page() upon do_kexec_load() failure.
2018-05-03 21:04 ` kernel BUG at include/linux/mm.h:LINE! syzbot
@ 2018-05-03 23:38 ` Tetsuo Handa
0 siblings, 0 replies; 9+ messages in thread
From: Tetsuo Handa @ 2018-05-03 23:38 UTC (permalink / raw)
To: ying.huang, hpa, mingo, mingo, syzbot+d96f60296ef613fe1d69
Cc: kirill.shutemov, akpm, bhe, dyoung, linux-kernel, prudo,
syzkaller-bugs, takahiro.akashi, tglx, thomas.lendacky, x86,
xlpang
>From 91a78abed036e1662b11cb54ae6300864e17b709 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Fri, 4 May 2018 08:26:41 +0900
Subject: [PATCH v2] x86/kexec: avoid double free_page() upon do_kexec_load() failure.
syzbot is reporting crashes after memory allocation failure inside
do_kexec_load() [1]. This is because free_transition_pgtable() is called
by both init_transition_pgtable() and machine_kexec_cleanup() when memory
allocation failed inside init_transition_pgtable().
Regarding 32bit code, machine_kexec_free_page_tables() is called by both
machine_kexec_alloc_page_tables() and machine_kexec_cleanup() when memory
allocation failed inside machine_kexec_alloc_page_tables().
Fix this by leaving the error handling to machine_kexec_cleanup().
[1] https://syzkaller.appspot.com/bug?id=91e52396168cf2bdd572fe1e1bc0bc645c1c6b40
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reported-by: syzbot <syzbot+d96f60296ef613fe1d69@syzkaller.appspotmail.com>
Fixes: f5deb79679af6eb4 ("x86: kexec: Use one page table in x86_64 machine_kexec")
Fixes: 92be3d6bdf2cb349 ("kexec/i386: allocate page table pages dynamically")
Cc: Huang Ying <ying.huang@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@elte.hu>
---
arch/x86/kernel/machine_kexec_32.c | 1 -
arch/x86/kernel/machine_kexec_64.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 60cdec6..170fbf8 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -79,7 +79,6 @@ static int machine_kexec_alloc_page_tables(struct kimage *image)
!image->arch.pmd0 || !image->arch.pmd1 ||
#endif
!image->arch.pte0 || !image->arch.pte1) {
- machine_kexec_free_page_tables(image);
return -ENOMEM;
}
return 0;
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index a5e55d8..ffe0174 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -91,7 +91,6 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC));
return 0;
err:
- free_transition_pgtable(image);
return result;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: kernel BUG at include/linux/mm.h:LINE!
2018-05-01 10:10 ` Tetsuo Handa
@ 2018-05-04 0:32 ` Baoquan He
2018-05-08 11:26 ` [PATCH v2] x86/kexec: avoid double free_page() upon do_kexec_load() failure Tetsuo Handa
0 siblings, 1 reply; 9+ messages in thread
From: Baoquan He @ 2018-05-04 0:32 UTC (permalink / raw)
To: Tetsuo Handa
Cc: syzbot, kirill.shutemov, linux-kernel, syzkaller-bugs,
Huang Ying, H. Peter Anvin, Ingo Molnar, akpm, dyoung, mingo,
prudo, takahiro.akashi, tglx, thomas.lendacky, x86
On 05/01/18 at 07:10pm, Tetsuo Handa wrote:
> From d54b2acf63191eba3d5052bf34fe6d26e3580ac2 Mon Sep 17 00:00:00 2001
> From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Date: Tue, 1 May 2018 15:36:52 +0900
> Subject: [PATCH] x86/kexec: avoid double free_page() upon do_kexec_load()
> failure.
>
> syzbot is reporting crashes after memory allocation failure inside
> do_kexec_load() [1]. This is because free_transition_pgtable() is called
> by both init_transition_pgtable() and machine_kexec_cleanup() when memory
> allocation failed inside init_transition_pgtable().
>
> Regarding 32bit code, machine_kexec_free_page_tables() is called by both
> machine_kexec_alloc_page_tables() and machine_kexec_cleanup() when memory
> allocation failed inside machine_kexec_alloc_page_tables().
>
> Fix this by explicitly setting NULL after free_page().
Setting them NULL after free_page() is a good idea. Maybe can remove the
double calling of free_transition_pgtable() too in init_transition_pgtable()
because the returned value will trigger the later calling.
>
> [1] https://syzkaller.appspot.com/bug?id=91e52396168cf2bdd572fe1e1bc0bc645c1c6b40
>
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Reported-by: syzbot <syzbot+d96f60296ef613fe1d69@syzkaller.appspotmail.com>
> Fixes: f5deb79679af6eb4 ("x86: kexec: Use one page table in x86_64 machine_kexec")
> Fixes: 92be3d6bdf2cb349 ("kexec/i386: allocate page table pages dynamically")
> Cc: Huang Ying <ying.huang@intel.com>
> Cc: H. Peter Anvin <hpa@zytor.com>
> Cc: Ingo Molnar <mingo@elte.hu>
> ---
> arch/x86/kernel/machine_kexec_32.c | 5 +++++
> arch/x86/kernel/machine_kexec_64.c | 4 ++++
> 2 files changed, 9 insertions(+)
>
> diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
> index 60cdec6..ceccfe4 100644
> --- a/arch/x86/kernel/machine_kexec_32.c
> +++ b/arch/x86/kernel/machine_kexec_32.c
> @@ -57,12 +57,17 @@ static void load_segments(void)
> static void machine_kexec_free_page_tables(struct kimage *image)
> {
> free_page((unsigned long)image->arch.pgd);
> + image->arch.pgd = NULL;
> #ifdef CONFIG_X86_PAE
> free_page((unsigned long)image->arch.pmd0);
> + image->arch.pmd0 = NULL;
> free_page((unsigned long)image->arch.pmd1);
> + image->arch.pmd1 = NULL;
> #endif
> free_page((unsigned long)image->arch.pte0);
> + image->arch.pte0 = NULL;
> free_page((unsigned long)image->arch.pte1);
> + image->arch.pte1 = NULL;
> }
>
> static int machine_kexec_alloc_page_tables(struct kimage *image)
> diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
> index a5e55d8..76aaee9 100644
> --- a/arch/x86/kernel/machine_kexec_64.c
> +++ b/arch/x86/kernel/machine_kexec_64.c
> @@ -39,9 +39,13 @@
> static void free_transition_pgtable(struct kimage *image)
> {
> free_page((unsigned long)image->arch.p4d);
> + image->arch.p4d = NULL;
> free_page((unsigned long)image->arch.pud);
> + image->arch.pud = NULL;
> free_page((unsigned long)image->arch.pmd);
> + image->arch.pmd = NULL;
> free_page((unsigned long)image->arch.pte);
> + image->arch.pte = NULL;
> }
>
> static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
> --
> 1.8.3.1
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2] x86/kexec: avoid double free_page() upon do_kexec_load() failure.
2018-05-04 0:32 ` Baoquan He
@ 2018-05-08 11:26 ` Tetsuo Handa
2018-05-09 10:42 ` [PATCH v3] " Tetsuo Handa
0 siblings, 1 reply; 9+ messages in thread
From: Tetsuo Handa @ 2018-05-08 11:26 UTC (permalink / raw)
To: bhe, ying.huang, hpa, mingo
Cc: syzbot+d96f60296ef613fe1d69, kirill.shutemov, linux-kernel,
syzkaller-bugs, akpm, dyoung, mingo, prudo, takahiro.akashi,
tglx, thomas.lendacky, x86
Baoquan He wrote:
> On 05/01/18 at 07:10pm, Tetsuo Handa wrote:
> > From d54b2acf63191eba3d5052bf34fe6d26e3580ac2 Mon Sep 17 00:00:00 2001
> > From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> > Date: Tue, 1 May 2018 15:36:52 +0900
> > Subject: [PATCH] x86/kexec: avoid double free_page() upon do_kexec_load()
> > failure.
> >
> > syzbot is reporting crashes after memory allocation failure inside
> > do_kexec_load() [1]. This is because free_transition_pgtable() is called
> > by both init_transition_pgtable() and machine_kexec_cleanup() when memory
> > allocation failed inside init_transition_pgtable().
> >
> > Regarding 32bit code, machine_kexec_free_page_tables() is called by both
> > machine_kexec_alloc_page_tables() and machine_kexec_cleanup() when memory
> > allocation failed inside machine_kexec_alloc_page_tables().
> >
> > Fix this by explicitly setting NULL after free_page().
>
> Setting them NULL after free_page() is a good idea.
That's what the V1 patch did.
> Maybe can remove the
> double calling of free_transition_pgtable() too in init_transition_pgtable()
> because the returned value will trigger the later calling.
That's what the V2 patch did. You can apply V1 or V2 or V1 + V2.
>From 91a78abed036e1662b11cb54ae6300864e17b709 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Fri, 4 May 2018 08:26:41 +0900
Subject: [PATCH v2] x86/kexec: avoid double free_page() upon do_kexec_load() failure.
syzbot is reporting crashes after memory allocation failure inside
do_kexec_load() [1]. This is because free_transition_pgtable() is called
by both init_transition_pgtable() and machine_kexec_cleanup() when memory
allocation failed inside init_transition_pgtable().
Regarding 32bit code, machine_kexec_free_page_tables() is called by both
machine_kexec_alloc_page_tables() and machine_kexec_cleanup() when memory
allocation failed inside machine_kexec_alloc_page_tables().
Fix this by leaving the error handling to machine_kexec_cleanup().
[1] https://syzkaller.appspot.com/bug?id=91e52396168cf2bdd572fe1e1bc0bc645c1c6b40
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reported-by: syzbot <syzbot+d96f60296ef613fe1d69@syzkaller.appspotmail.com>
Fixes: f5deb79679af6eb4 ("x86: kexec: Use one page table in x86_64 machine_kexec")
Fixes: 92be3d6bdf2cb349 ("kexec/i386: allocate page table pages dynamically")
Cc: Huang Ying <ying.huang@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@elte.hu>
---
arch/x86/kernel/machine_kexec_32.c | 1 -
arch/x86/kernel/machine_kexec_64.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 60cdec6..170fbf8 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -79,7 +79,6 @@ static int machine_kexec_alloc_page_tables(struct kimage *image)
!image->arch.pmd0 || !image->arch.pmd1 ||
#endif
!image->arch.pte0 || !image->arch.pte1) {
- machine_kexec_free_page_tables(image);
return -ENOMEM;
}
return 0;
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index a5e55d8..ffe0174 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -91,7 +91,6 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC));
return 0;
err:
- free_transition_pgtable(image);
return result;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v3] x86/kexec: avoid double free_page() upon do_kexec_load() failure.
2018-05-08 11:26 ` [PATCH v2] x86/kexec: avoid double free_page() upon do_kexec_load() failure Tetsuo Handa
@ 2018-05-09 10:42 ` Tetsuo Handa
2018-05-10 6:39 ` Baoquan He
2018-05-13 17:54 ` [tip:x86/urgent] x86/kexec: Avoid " tip-bot for Tetsuo Handa
0 siblings, 2 replies; 9+ messages in thread
From: Tetsuo Handa @ 2018-05-09 10:42 UTC (permalink / raw)
To: bhe, ying.huang, hpa, mingo
Cc: syzbot+d96f60296ef613fe1d69, kirill.shutemov, linux-kernel,
syzkaller-bugs, akpm, dyoung, mingo, prudo, takahiro.akashi,
tglx, thomas.lendacky, x86
>From ff82bedd3e12f0d3353282054ae48c3bd8c72012 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Wed, 9 May 2018 12:12:39 +0900
Subject: [PATCH v3] x86/kexec: avoid double free_page() upon do_kexec_load() failure.
syzbot is reporting crashes after memory allocation failure inside
do_kexec_load() [1]. This is because free_transition_pgtable() is called
by both init_transition_pgtable() and machine_kexec_cleanup() when memory
allocation failed inside init_transition_pgtable().
Regarding 32bit code, machine_kexec_free_page_tables() is called by both
machine_kexec_alloc_page_tables() and machine_kexec_cleanup() when memory
allocation failed inside machine_kexec_alloc_page_tables().
Fix this by leaving the error handling to machine_kexec_cleanup()
(and optionally setting NULL after free_page()).
[1] https://syzkaller.appspot.com/bug?id=91e52396168cf2bdd572fe1e1bc0bc645c1c6b40
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reported-by: syzbot <syzbot+d96f60296ef613fe1d69@syzkaller.appspotmail.com>
Fixes: f5deb79679af6eb4 ("x86: kexec: Use one page table in x86_64 machine_kexec")
Fixes: 92be3d6bdf2cb349 ("kexec/i386: allocate page table pages dynamically")
Cc: Huang Ying <ying.huang@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Ingo Molnar <mingo@elte.hu>
---
arch/x86/kernel/machine_kexec_32.c | 6 +++++-
arch/x86/kernel/machine_kexec_64.c | 5 ++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 60cdec6..d1ab07e 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -57,12 +57,17 @@ static void load_segments(void)
static void machine_kexec_free_page_tables(struct kimage *image)
{
free_page((unsigned long)image->arch.pgd);
+ image->arch.pgd = NULL;
#ifdef CONFIG_X86_PAE
free_page((unsigned long)image->arch.pmd0);
+ image->arch.pmd0 = NULL;
free_page((unsigned long)image->arch.pmd1);
+ image->arch.pmd1 = NULL;
#endif
free_page((unsigned long)image->arch.pte0);
+ image->arch.pte0 = NULL;
free_page((unsigned long)image->arch.pte1);
+ image->arch.pte1 = NULL;
}
static int machine_kexec_alloc_page_tables(struct kimage *image)
@@ -79,7 +84,6 @@ static int machine_kexec_alloc_page_tables(struct kimage *image)
!image->arch.pmd0 || !image->arch.pmd1 ||
#endif
!image->arch.pte0 || !image->arch.pte1) {
- machine_kexec_free_page_tables(image);
return -ENOMEM;
}
return 0;
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index a5e55d8..6010449 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -39,9 +39,13 @@
static void free_transition_pgtable(struct kimage *image)
{
free_page((unsigned long)image->arch.p4d);
+ image->arch.p4d = NULL;
free_page((unsigned long)image->arch.pud);
+ image->arch.pud = NULL;
free_page((unsigned long)image->arch.pmd);
+ image->arch.pmd = NULL;
free_page((unsigned long)image->arch.pte);
+ image->arch.pte = NULL;
}
static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
@@ -91,7 +95,6 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC));
return 0;
err:
- free_transition_pgtable(image);
return result;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v3] x86/kexec: avoid double free_page() upon do_kexec_load() failure.
2018-05-09 10:42 ` [PATCH v3] " Tetsuo Handa
@ 2018-05-10 6:39 ` Baoquan He
2018-05-13 17:54 ` [tip:x86/urgent] x86/kexec: Avoid " tip-bot for Tetsuo Handa
1 sibling, 0 replies; 9+ messages in thread
From: Baoquan He @ 2018-05-10 6:39 UTC (permalink / raw)
To: Tetsuo Handa
Cc: ying.huang, hpa, mingo, syzbot+d96f60296ef613fe1d69,
kirill.shutemov, linux-kernel, syzkaller-bugs, akpm, dyoung,
mingo, prudo, takahiro.akashi, tglx, thomas.lendacky, x86
On 05/09/18 at 07:42pm, Tetsuo Handa wrote:
> >From ff82bedd3e12f0d3353282054ae48c3bd8c72012 Mon Sep 17 00:00:00 2001
> From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Date: Wed, 9 May 2018 12:12:39 +0900
> Subject: [PATCH v3] x86/kexec: avoid double free_page() upon do_kexec_load() failure.
>
> syzbot is reporting crashes after memory allocation failure inside
> do_kexec_load() [1]. This is because free_transition_pgtable() is called
> by both init_transition_pgtable() and machine_kexec_cleanup() when memory
> allocation failed inside init_transition_pgtable().
>
> Regarding 32bit code, machine_kexec_free_page_tables() is called by both
> machine_kexec_alloc_page_tables() and machine_kexec_cleanup() when memory
> allocation failed inside machine_kexec_alloc_page_tables().
>
> Fix this by leaving the error handling to machine_kexec_cleanup()
> (and optionally setting NULL after free_page()).
>
> [1] https://syzkaller.appspot.com/bug?id=91e52396168cf2bdd572fe1e1bc0bc645c1c6b40
>
> Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
> Reported-by: syzbot <syzbot+d96f60296ef613fe1d69@syzkaller.appspotmail.com>
> Fixes: f5deb79679af6eb4 ("x86: kexec: Use one page table in x86_64 machine_kexec")
> Fixes: 92be3d6bdf2cb349 ("kexec/i386: allocate page table pages dynamically")
> Cc: Huang Ying <ying.huang@intel.com>
> Cc: H. Peter Anvin <hpa@zytor.com>
> Cc: Ingo Molnar <mingo@elte.hu>
> ---
> arch/x86/kernel/machine_kexec_32.c | 6 +++++-
> arch/x86/kernel/machine_kexec_64.c | 5 ++++-
> 2 files changed, 9 insertions(+), 2 deletions(-)
Looks good to me, thx!
Acked-by: Baoquan He <bhe@redhat.com>
Thanks
Baoquan
>
> diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
> index 60cdec6..d1ab07e 100644
> --- a/arch/x86/kernel/machine_kexec_32.c
> +++ b/arch/x86/kernel/machine_kexec_32.c
> @@ -57,12 +57,17 @@ static void load_segments(void)
> static void machine_kexec_free_page_tables(struct kimage *image)
> {
> free_page((unsigned long)image->arch.pgd);
> + image->arch.pgd = NULL;
> #ifdef CONFIG_X86_PAE
> free_page((unsigned long)image->arch.pmd0);
> + image->arch.pmd0 = NULL;
> free_page((unsigned long)image->arch.pmd1);
> + image->arch.pmd1 = NULL;
> #endif
> free_page((unsigned long)image->arch.pte0);
> + image->arch.pte0 = NULL;
> free_page((unsigned long)image->arch.pte1);
> + image->arch.pte1 = NULL;
> }
>
> static int machine_kexec_alloc_page_tables(struct kimage *image)
> @@ -79,7 +84,6 @@ static int machine_kexec_alloc_page_tables(struct kimage *image)
> !image->arch.pmd0 || !image->arch.pmd1 ||
> #endif
> !image->arch.pte0 || !image->arch.pte1) {
> - machine_kexec_free_page_tables(image);
> return -ENOMEM;
> }
> return 0;
> diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
> index a5e55d8..6010449 100644
> --- a/arch/x86/kernel/machine_kexec_64.c
> +++ b/arch/x86/kernel/machine_kexec_64.c
> @@ -39,9 +39,13 @@
> static void free_transition_pgtable(struct kimage *image)
> {
> free_page((unsigned long)image->arch.p4d);
> + image->arch.p4d = NULL;
> free_page((unsigned long)image->arch.pud);
> + image->arch.pud = NULL;
> free_page((unsigned long)image->arch.pmd);
> + image->arch.pmd = NULL;
> free_page((unsigned long)image->arch.pte);
> + image->arch.pte = NULL;
> }
>
> static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
> @@ -91,7 +95,6 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
> set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC));
> return 0;
> err:
> - free_transition_pgtable(image);
> return result;
> }
>
> --
> 1.8.3.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [tip:x86/urgent] x86/kexec: Avoid double free_page() upon do_kexec_load() failure
2018-05-09 10:42 ` [PATCH v3] " Tetsuo Handa
2018-05-10 6:39 ` Baoquan He
@ 2018-05-13 17:54 ` tip-bot for Tetsuo Handa
1 sibling, 0 replies; 9+ messages in thread
From: tip-bot for Tetsuo Handa @ 2018-05-13 17:54 UTC (permalink / raw)
To: linux-tip-commits
Cc: tglx, penguin-kernel, mingo, bhe, ying.huang, hpa, linux-kernel,
syzbot+d96f60296ef613fe1d69
Commit-ID: a466ef76b815b86748d9870ef2a430af7b39c710
Gitweb: https://git.kernel.org/tip/a466ef76b815b86748d9870ef2a430af7b39c710
Author: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
AuthorDate: Wed, 9 May 2018 19:42:20 +0900
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sun, 13 May 2018 19:50:06 +0200
x86/kexec: Avoid double free_page() upon do_kexec_load() failure
>From ff82bedd3e12f0d3353282054ae48c3bd8c72012 Mon Sep 17 00:00:00 2001
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Date: Wed, 9 May 2018 12:12:39 +0900
Subject: [PATCH v3] x86/kexec: avoid double free_page() upon do_kexec_load() failure.
syzbot is reporting crashes after memory allocation failure inside
do_kexec_load() [1]. This is because free_transition_pgtable() is called
by both init_transition_pgtable() and machine_kexec_cleanup() when memory
allocation failed inside init_transition_pgtable().
Regarding 32bit code, machine_kexec_free_page_tables() is called by both
machine_kexec_alloc_page_tables() and machine_kexec_cleanup() when memory
allocation failed inside machine_kexec_alloc_page_tables().
Fix this by leaving the error handling to machine_kexec_cleanup()
(and optionally setting NULL after free_page()).
[1] https://syzkaller.appspot.com/bug?id=91e52396168cf2bdd572fe1e1bc0bc645c1c6b40
Fixes: f5deb79679af6eb4 ("x86: kexec: Use one page table in x86_64 machine_kexec")
Fixes: 92be3d6bdf2cb349 ("kexec/i386: allocate page table pages dynamically")
Reported-by: syzbot <syzbot+d96f60296ef613fe1d69@syzkaller.appspotmail.com>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Baoquan He <bhe@redhat.com>
Cc: thomas.lendacky@amd.com
Cc: prudo@linux.vnet.ibm.com
Cc: Huang Ying <ying.huang@intel.com>
Cc: syzkaller-bugs@googlegroups.com
Cc: takahiro.akashi@linaro.org
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: akpm@linux-foundation.org
Cc: dyoung@redhat.com
Cc: kirill.shutemov@linux.intel.com
Link: https://lkml.kernel.org/r/201805091942.DGG12448.tMFVFSJFQOOLHO@I-love.SAKURA.ne.jp
---
arch/x86/kernel/machine_kexec_32.c | 6 +++++-
arch/x86/kernel/machine_kexec_64.c | 5 ++++-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c
index 60cdec6628b0..d1ab07ec8c9a 100644
--- a/arch/x86/kernel/machine_kexec_32.c
+++ b/arch/x86/kernel/machine_kexec_32.c
@@ -57,12 +57,17 @@ static void load_segments(void)
static void machine_kexec_free_page_tables(struct kimage *image)
{
free_page((unsigned long)image->arch.pgd);
+ image->arch.pgd = NULL;
#ifdef CONFIG_X86_PAE
free_page((unsigned long)image->arch.pmd0);
+ image->arch.pmd0 = NULL;
free_page((unsigned long)image->arch.pmd1);
+ image->arch.pmd1 = NULL;
#endif
free_page((unsigned long)image->arch.pte0);
+ image->arch.pte0 = NULL;
free_page((unsigned long)image->arch.pte1);
+ image->arch.pte1 = NULL;
}
static int machine_kexec_alloc_page_tables(struct kimage *image)
@@ -79,7 +84,6 @@ static int machine_kexec_alloc_page_tables(struct kimage *image)
!image->arch.pmd0 || !image->arch.pmd1 ||
#endif
!image->arch.pte0 || !image->arch.pte1) {
- machine_kexec_free_page_tables(image);
return -ENOMEM;
}
return 0;
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index a5e55d832d0a..6010449ca6d2 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -39,9 +39,13 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
static void free_transition_pgtable(struct kimage *image)
{
free_page((unsigned long)image->arch.p4d);
+ image->arch.p4d = NULL;
free_page((unsigned long)image->arch.pud);
+ image->arch.pud = NULL;
free_page((unsigned long)image->arch.pmd);
+ image->arch.pmd = NULL;
free_page((unsigned long)image->arch.pte);
+ image->arch.pte = NULL;
}
static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
@@ -91,7 +95,6 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC));
return 0;
err:
- free_transition_pgtable(image);
return result;
}
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2018-05-13 17:55 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-01 8:31 kernel BUG at include/linux/mm.h:LINE! syzbot
2018-05-01 10:10 ` Tetsuo Handa
2018-05-04 0:32 ` Baoquan He
2018-05-08 11:26 ` [PATCH v2] x86/kexec: avoid double free_page() upon do_kexec_load() failure Tetsuo Handa
2018-05-09 10:42 ` [PATCH v3] " Tetsuo Handa
2018-05-10 6:39 ` Baoquan He
2018-05-13 17:54 ` [tip:x86/urgent] x86/kexec: Avoid " tip-bot for Tetsuo Handa
2018-05-03 21:04 ` kernel BUG at include/linux/mm.h:LINE! syzbot
2018-05-03 23:38 ` [PATCH v2] x86/kexec: avoid double free_page() upon do_kexec_load() failure Tetsuo Handa
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).