All of 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.