提交 184d47f0 编写于 作者: K Kees Cook 提交者: Ingo Molnar

x86/mm: Avoid VLA in pgd_alloc()

Arnd Bergmann reported that turning on -Wvla found a new (unintended) VLA usage:

  arch/x86/mm/pgtable.c: In function 'pgd_alloc':
  include/linux/build_bug.h:29:45: error: ISO C90 forbids variable length array 'u_pmds' [-Werror=vla]
  arch/x86/mm/pgtable.c:190:34: note: in expansion of macro 'static_cpu_has'
   #define PREALLOCATED_USER_PMDS  (static_cpu_has(X86_FEATURE_PTI) ? \
                                    ^~~~~~~~~~~~~~
  arch/x86/mm/pgtable.c:431:16: note: in expansion of macro 'PREALLOCATED_USER_PMDS'
    pmd_t *u_pmds[PREALLOCATED_USER_PMDS];
                ^~~~~~~~~~~~~~~~~~~~~~

Use the actual size of the array that is used for X86_FEATURE_PTI,
which is known at build time, instead of the variable size.

[ mingo: Squashed original fix with followup fix to avoid bisection breakage, wrote new changelog. ]
Reported-by: NArnd Bergmann <arnd@arndb.de>
Original-written-by: NArnd Bergmann <arnd@arndb.de>
Reported-by: NBorislav Petkov <bp@alien8.de>
Signed-off-by: NKees Cook <keescook@chromium.org>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Joerg Roedel <jroedel@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Toshi Kani <toshi.kani@hpe.com>
Fixes: 1be3f247c288 ("x86/mm: Avoid VLA in pgd_alloc()")
Link: http://lkml.kernel.org/r/20181008235434.GA35035@beastSigned-off-by: NIngo Molnar <mingo@kernel.org>
上级 49e00eee
...@@ -115,6 +115,8 @@ static inline void pgd_list_del(pgd_t *pgd) ...@@ -115,6 +115,8 @@ static inline void pgd_list_del(pgd_t *pgd)
#define UNSHARED_PTRS_PER_PGD \ #define UNSHARED_PTRS_PER_PGD \
(SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD) (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD)
#define MAX_UNSHARED_PTRS_PER_PGD \
max_t(size_t, KERNEL_PGD_BOUNDARY, PTRS_PER_PGD)
static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm) static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm)
...@@ -181,6 +183,7 @@ static void pgd_dtor(pgd_t *pgd) ...@@ -181,6 +183,7 @@ static void pgd_dtor(pgd_t *pgd)
* and initialize the kernel pmds here. * and initialize the kernel pmds here.
*/ */
#define PREALLOCATED_PMDS UNSHARED_PTRS_PER_PGD #define PREALLOCATED_PMDS UNSHARED_PTRS_PER_PGD
#define MAX_PREALLOCATED_PMDS MAX_UNSHARED_PTRS_PER_PGD
/* /*
* We allocate separate PMDs for the kernel part of the user page-table * We allocate separate PMDs for the kernel part of the user page-table
...@@ -189,6 +192,7 @@ static void pgd_dtor(pgd_t *pgd) ...@@ -189,6 +192,7 @@ static void pgd_dtor(pgd_t *pgd)
*/ */
#define PREALLOCATED_USER_PMDS (static_cpu_has(X86_FEATURE_PTI) ? \ #define PREALLOCATED_USER_PMDS (static_cpu_has(X86_FEATURE_PTI) ? \
KERNEL_PGD_PTRS : 0) KERNEL_PGD_PTRS : 0)
#define MAX_PREALLOCATED_USER_PMDS KERNEL_PGD_PTRS
void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd) void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
{ {
...@@ -210,7 +214,9 @@ void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd) ...@@ -210,7 +214,9 @@ void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd)
/* No need to prepopulate any pagetable entries in non-PAE modes. */ /* No need to prepopulate any pagetable entries in non-PAE modes. */
#define PREALLOCATED_PMDS 0 #define PREALLOCATED_PMDS 0
#define MAX_PREALLOCATED_PMDS 0
#define PREALLOCATED_USER_PMDS 0 #define PREALLOCATED_USER_PMDS 0
#define MAX_PREALLOCATED_USER_PMDS 0
#endif /* CONFIG_X86_PAE */ #endif /* CONFIG_X86_PAE */
static void free_pmds(struct mm_struct *mm, pmd_t *pmds[], int count) static void free_pmds(struct mm_struct *mm, pmd_t *pmds[], int count)
...@@ -428,8 +434,8 @@ static inline void _pgd_free(pgd_t *pgd) ...@@ -428,8 +434,8 @@ static inline void _pgd_free(pgd_t *pgd)
pgd_t *pgd_alloc(struct mm_struct *mm) pgd_t *pgd_alloc(struct mm_struct *mm)
{ {
pgd_t *pgd; pgd_t *pgd;
pmd_t *u_pmds[PREALLOCATED_USER_PMDS]; pmd_t *u_pmds[MAX_PREALLOCATED_USER_PMDS];
pmd_t *pmds[PREALLOCATED_PMDS]; pmd_t *pmds[MAX_PREALLOCATED_PMDS];
pgd = _pgd_alloc(); pgd = _pgd_alloc();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册