Skip to content

Commit

Permalink
x86/mm/cpa: In populate_pgd(), don't set the PGD entry until it's pop…
Browse files Browse the repository at this point in the history
…ulated

This avoids pointless races in which another CPU or task might see a
partially populated global PGD entry.  These races should normally
be harmless, but, if another CPU propagates the entry via
vmalloc_fault() and then populate_pgd() fails (due to memory allocation
failure, for example), this prevents a use-after-free of the PGD
entry.

Signed-off-by: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/bf99df27eac6835f687005364bd1fbd89130946c.1468527351.git.luto@kernel.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Andy Lutomirski authored and Ingo Molnar committed Jul 15, 2016
1 parent af2cf27 commit 360cb4d
Showing 1 changed file with 6 additions and 3 deletions.
9 changes: 6 additions & 3 deletions arch/x86/mm/pageattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1104,20 +1104,23 @@ static int populate_pgd(struct cpa_data *cpa, unsigned long addr)
pud = (pud_t *)get_zeroed_page(GFP_KERNEL | __GFP_NOTRACK);
if (!pud)
return -1;

set_pgd(pgd_entry, __pgd(__pa(pud) | _KERNPG_TABLE));
}

pgprot_val(pgprot) &= ~pgprot_val(cpa->mask_clr);
pgprot_val(pgprot) |= pgprot_val(cpa->mask_set);

ret = populate_pud(cpa, addr, pgd_entry, pgprot);
if (ret < 0) {
unmap_pgd_range(cpa->pgd, addr,
if (pud)
free_page((unsigned long)pud);
unmap_pud_range(pgd_entry, addr,
addr + (cpa->numpages << PAGE_SHIFT));
return ret;
}

if (pud)
set_pgd(pgd_entry, __pgd(__pa(pud) | _KERNPG_TABLE));

cpa->numpages = ret;
return 0;
}
Expand Down

0 comments on commit 360cb4d

Please sign in to comment.