diff options
author | Kees Cook <keescook@chromium.org> | 2018-10-08 19:54:34 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2018-10-09 02:55:07 -0400 |
commit | 184d47f0fd365108bd06ab26cdb3450b716269fd (patch) | |
tree | 4be24aedef29acd528c29ee904868e8539c2bc9a | |
parent | 49e00eee00612b1357596fed8a88b621a7648c14 (diff) |
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 <arnd@arndb.de>
Original-written-by: Arnd Bergmann <arnd@arndb.de>
Reported-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Kees 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@beast
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/mm/pgtable.c | 10 |
1 files 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) | |||
115 | 115 | ||
116 | #define UNSHARED_PTRS_PER_PGD \ | 116 | #define UNSHARED_PTRS_PER_PGD \ |
117 | (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD) | 117 | (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD) |
118 | #define MAX_UNSHARED_PTRS_PER_PGD \ | ||
119 | max_t(size_t, KERNEL_PGD_BOUNDARY, PTRS_PER_PGD) | ||
118 | 120 | ||
119 | 121 | ||
120 | static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm) | 122 | static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm) |
@@ -181,6 +183,7 @@ static void pgd_dtor(pgd_t *pgd) | |||
181 | * and initialize the kernel pmds here. | 183 | * and initialize the kernel pmds here. |
182 | */ | 184 | */ |
183 | #define PREALLOCATED_PMDS UNSHARED_PTRS_PER_PGD | 185 | #define PREALLOCATED_PMDS UNSHARED_PTRS_PER_PGD |
186 | #define MAX_PREALLOCATED_PMDS MAX_UNSHARED_PTRS_PER_PGD | ||
184 | 187 | ||
185 | /* | 188 | /* |
186 | * We allocate separate PMDs for the kernel part of the user page-table | 189 | * 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 | */ | 192 | */ |
190 | #define PREALLOCATED_USER_PMDS (static_cpu_has(X86_FEATURE_PTI) ? \ | 193 | #define PREALLOCATED_USER_PMDS (static_cpu_has(X86_FEATURE_PTI) ? \ |
191 | KERNEL_PGD_PTRS : 0) | 194 | KERNEL_PGD_PTRS : 0) |
195 | #define MAX_PREALLOCATED_USER_PMDS KERNEL_PGD_PTRS | ||
192 | 196 | ||
193 | void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd) | 197 | void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd) |
194 | { | 198 | { |
@@ -210,7 +214,9 @@ void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd) | |||
210 | 214 | ||
211 | /* No need to prepopulate any pagetable entries in non-PAE modes. */ | 215 | /* No need to prepopulate any pagetable entries in non-PAE modes. */ |
212 | #define PREALLOCATED_PMDS 0 | 216 | #define PREALLOCATED_PMDS 0 |
217 | #define MAX_PREALLOCATED_PMDS 0 | ||
213 | #define PREALLOCATED_USER_PMDS 0 | 218 | #define PREALLOCATED_USER_PMDS 0 |
219 | #define MAX_PREALLOCATED_USER_PMDS 0 | ||
214 | #endif /* CONFIG_X86_PAE */ | 220 | #endif /* CONFIG_X86_PAE */ |
215 | 221 | ||
216 | static void free_pmds(struct mm_struct *mm, pmd_t *pmds[], int count) | 222 | 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 | pgd_t *pgd_alloc(struct mm_struct *mm) | 434 | pgd_t *pgd_alloc(struct mm_struct *mm) |
429 | { | 435 | { |
430 | pgd_t *pgd; | 436 | pgd_t *pgd; |
431 | pmd_t *u_pmds[PREALLOCATED_USER_PMDS]; | 437 | pmd_t *u_pmds[MAX_PREALLOCATED_USER_PMDS]; |
432 | pmd_t *pmds[PREALLOCATED_PMDS]; | 438 | pmd_t *pmds[MAX_PREALLOCATED_PMDS]; |
433 | 439 | ||
434 | pgd = _pgd_alloc(); | 440 | pgd = _pgd_alloc(); |
435 | 441 | ||