Skip to content

Commit ceca927

Browse files
keesctmarinas
authored andcommitted
arm64: mm: Fix CFI failure due to kpti_ng_pgd_alloc function signature
Seen during KPTI initialization: CFI failure at create_kpti_ng_temp_pgd+0x124/0xce8 (target: kpti_ng_pgd_alloc+0x0/0x14; expected type: 0xd61b88b6) The call site is alloc_init_pud() at arch/arm64/mm/mmu.c: pud_phys = pgtable_alloc(TABLE_PUD); alloc_init_pud() has the prototype: static void alloc_init_pud(p4d_t *p4dp, unsigned long addr, unsigned long end, phys_addr_t phys, pgprot_t prot, phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags) where the pgtable_alloc() prototype is declared. The target (kpti_ng_pgd_alloc) is used in arch/arm64/kernel/cpufeature.c: create_kpti_ng_temp_pgd(kpti_ng_temp_pgd, __pa(alloc), KPTI_NG_TEMP_VA, PAGE_SIZE, PAGE_KERNEL, kpti_ng_pgd_alloc, 0); which is an alias for __create_pgd_mapping_locked() with prototype: extern __alias(__create_pgd_mapping_locked) void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt, phys_addr_t size, pgprot_t prot, phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags); __create_pgd_mapping_locked() passes the function pointer down: __create_pgd_mapping_locked() -> alloc_init_p4d() -> alloc_init_pud() But the target function (kpti_ng_pgd_alloc) has the wrong signature: static phys_addr_t __init kpti_ng_pgd_alloc(int shift); The "int" should be "enum pgtable_type". To make "enum pgtable_type" available to cpufeature.c, move enum pgtable_type definition from arch/arm64/mm/mmu.c to arch/arm64/include/asm/mmu.h. Adjust kpti_ng_pgd_alloc to use "enum pgtable_type" instead of "int". The function behavior remains identical (parameter is unused). Fixes: c64f46e ("arm64: mm: use enum to identify pgtable level instead of *_SHIFT") Cc: <[email protected]> # 6.16.x Signed-off-by: Kees Cook <[email protected]> Acked-by: Ard Biesheuvel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Ryan Roberts <[email protected]> Signed-off-by: Catalin Marinas <[email protected]>
1 parent 8f5ae30 commit ceca927

File tree

3 files changed

+10
-9
lines changed

3 files changed

+10
-9
lines changed

arch/arm64/include/asm/mmu.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
#include <linux/refcount.h>
1818
#include <asm/cpufeature.h>
1919

20+
enum pgtable_type {
21+
TABLE_PTE,
22+
TABLE_PMD,
23+
TABLE_PUD,
24+
TABLE_P4D,
25+
};
26+
2027
typedef struct {
2128
atomic64_t id;
2229
#ifdef CONFIG_COMPAT

arch/arm64/kernel/cpufeature.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
#include <asm/hwcap.h>
8585
#include <asm/insn.h>
8686
#include <asm/kvm_host.h>
87+
#include <asm/mmu.h>
8788
#include <asm/mmu_context.h>
8889
#include <asm/mte.h>
8990
#include <asm/hypervisor.h>
@@ -1945,11 +1946,11 @@ static bool has_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
19451946
extern
19461947
void create_kpti_ng_temp_pgd(pgd_t *pgdir, phys_addr_t phys, unsigned long virt,
19471948
phys_addr_t size, pgprot_t prot,
1948-
phys_addr_t (*pgtable_alloc)(int), int flags);
1949+
phys_addr_t (*pgtable_alloc)(enum pgtable_type), int flags);
19491950

19501951
static phys_addr_t __initdata kpti_ng_temp_alloc;
19511952

1952-
static phys_addr_t __init kpti_ng_pgd_alloc(int shift)
1953+
static phys_addr_t __init kpti_ng_pgd_alloc(enum pgtable_type type)
19531954
{
19541955
kpti_ng_temp_alloc -= PAGE_SIZE;
19551956
return kpti_ng_temp_alloc;

arch/arm64/mm/mmu.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,6 @@
4747
#define NO_CONT_MAPPINGS BIT(1)
4848
#define NO_EXEC_MAPPINGS BIT(2) /* assumes FEAT_HPDS is not used */
4949

50-
enum pgtable_type {
51-
TABLE_PTE,
52-
TABLE_PMD,
53-
TABLE_PUD,
54-
TABLE_P4D,
55-
};
56-
5750
u64 kimage_voffset __ro_after_init;
5851
EXPORT_SYMBOL(kimage_voffset);
5952

0 commit comments

Comments
 (0)