Skip to content

Commit a466ef7

Browse files
Tetsuo HandaKAGA-KOKO
authored andcommitted
x86/kexec: Avoid double free_page() upon do_kexec_load() failure
>From ff82bedd3e12f0d3353282054ae48c3bd8c72012 Mon Sep 17 00:00:00 2001 From: Tetsuo Handa <[email protected]> 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: f5deb79 ("x86: kexec: Use one page table in x86_64 machine_kexec") Fixes: 92be3d6 ("kexec/i386: allocate page table pages dynamically") Reported-by: syzbot <[email protected]> Signed-off-by: Tetsuo Handa <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Acked-by: Baoquan He <[email protected]> Cc: [email protected] Cc: [email protected] Cc: Huang Ying <[email protected]> Cc: [email protected] Cc: [email protected] Cc: H. Peter Anvin <[email protected]> Cc: [email protected] Cc: [email protected] Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent ccda3c4 commit a466ef7

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

arch/x86/kernel/machine_kexec_32.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,17 @@ static void load_segments(void)
5757
static void machine_kexec_free_page_tables(struct kimage *image)
5858
{
5959
free_page((unsigned long)image->arch.pgd);
60+
image->arch.pgd = NULL;
6061
#ifdef CONFIG_X86_PAE
6162
free_page((unsigned long)image->arch.pmd0);
63+
image->arch.pmd0 = NULL;
6264
free_page((unsigned long)image->arch.pmd1);
65+
image->arch.pmd1 = NULL;
6366
#endif
6467
free_page((unsigned long)image->arch.pte0);
68+
image->arch.pte0 = NULL;
6569
free_page((unsigned long)image->arch.pte1);
70+
image->arch.pte1 = NULL;
6671
}
6772

6873
static int machine_kexec_alloc_page_tables(struct kimage *image)
@@ -79,7 +84,6 @@ static int machine_kexec_alloc_page_tables(struct kimage *image)
7984
!image->arch.pmd0 || !image->arch.pmd1 ||
8085
#endif
8186
!image->arch.pte0 || !image->arch.pte1) {
82-
machine_kexec_free_page_tables(image);
8387
return -ENOMEM;
8488
}
8589
return 0;

arch/x86/kernel/machine_kexec_64.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,13 @@ const struct kexec_file_ops * const kexec_file_loaders[] = {
3939
static void free_transition_pgtable(struct kimage *image)
4040
{
4141
free_page((unsigned long)image->arch.p4d);
42+
image->arch.p4d = NULL;
4243
free_page((unsigned long)image->arch.pud);
44+
image->arch.pud = NULL;
4345
free_page((unsigned long)image->arch.pmd);
46+
image->arch.pmd = NULL;
4447
free_page((unsigned long)image->arch.pte);
48+
image->arch.pte = NULL;
4549
}
4650

4751
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)
9195
set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC));
9296
return 0;
9397
err:
94-
free_transition_pgtable(image);
9598
return result;
9699
}
97100

0 commit comments

Comments
 (0)