Commit-ID:  184d47f0fd365108bd06ab26cdb3450b716269fd
Gitweb:     https://git.kernel.org/tip/184d47f0fd365108bd06ab26cdb3450b716269fd
Author:     Kees Cook <keesc...@chromium.org>
AuthorDate: Mon, 8 Oct 2018 16:54:34 -0700
Committer:  Ingo Molnar <mi...@kernel.org>
CommitDate: Tue, 9 Oct 2018 08:55:07 +0200

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: Arnd Bergmann <a...@arndb.de>
Original-written-by: Arnd Bergmann <a...@arndb.de>
Reported-by: Borislav Petkov <b...@alien8.de>
Signed-off-by: Kees Cook <keesc...@chromium.org>
Cc: Andrew Morton <a...@linux-foundation.org>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Arnd Bergmann <a...@arndb.de>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: Joerg Roedel <jroe...@suse.de>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Toshi Kani <toshi.k...@hpe.com>
Fixes: 1be3f247c288 ("x86/mm: Avoid VLA in pgd_alloc()")
Link: http://lkml.kernel.org/r/20181008235434.GA35035@beast
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 arch/x86/mm/pgtable.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
index 089e78c4effd..59274e2c1ac4 100644
--- a/arch/x86/mm/pgtable.c
+++ b/arch/x86/mm/pgtable.c
@@ -115,6 +115,8 @@ static inline void pgd_list_del(pgd_t *pgd)
 
 #define UNSHARED_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)
@@ -181,6 +183,7 @@ static void pgd_dtor(pgd_t *pgd)
  * and initialize the kernel pmds here.
  */
 #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
@@ -189,6 +192,7 @@ static void pgd_dtor(pgd_t *pgd)
  */
 #define PREALLOCATED_USER_PMDS  (static_cpu_has(X86_FEATURE_PTI) ? \
                                        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)
 {
@@ -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. */
 #define PREALLOCATED_PMDS      0
+#define MAX_PREALLOCATED_PMDS  0
 #define PREALLOCATED_USER_PMDS  0
+#define MAX_PREALLOCATED_USER_PMDS 0
 #endif /* CONFIG_X86_PAE */
 
 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)
 pgd_t *pgd_alloc(struct mm_struct *mm)
 {
        pgd_t *pgd;
-       pmd_t *u_pmds[PREALLOCATED_USER_PMDS];
-       pmd_t *pmds[PREALLOCATED_PMDS];
+       pmd_t *u_pmds[MAX_PREALLOCATED_USER_PMDS];
+       pmd_t *pmds[MAX_PREALLOCATED_PMDS];
 
        pgd = _pgd_alloc();
 

Reply via email to