diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> | 2020-12-02 10:08:54 +0530 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2020-12-04 01:01:27 +1100 |
commit | 61130e203dca3ba1f0c510eb12f7a4294e31a834 (patch) | |
tree | a96718f275df5029d775f4c7bea540ef8e879d30 /arch/powerpc | |
parent | c91435d95c49f4053b05ba03b41dd7ed0fbd6c71 (diff) |
powerpc/book3s64/kup: Check max key supported before enabling kup
Don't enable KUEP/KUAP if we support less than or equal to 3 keys.
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20201202043854.76406-1-aneesh.kumar@linux.ibm.com
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/include/asm/kup.h | 3 | ||||
-rw-r--r-- | arch/powerpc/mm/book3s64/pkeys.c | 33 | ||||
-rw-r--r-- | arch/powerpc/mm/init-common.c | 4 |
3 files changed, 26 insertions, 14 deletions
diff --git a/arch/powerpc/include/asm/kup.h b/arch/powerpc/include/asm/kup.h index 952be0414f43..f8ec679bd2de 100644 --- a/arch/powerpc/include/asm/kup.h +++ b/arch/powerpc/include/asm/kup.h @@ -44,6 +44,9 @@ #else /* !__ASSEMBLY__ */ +extern bool disable_kuep; +extern bool disable_kuap; + #include <linux/pgtable.h> void setup_kup(void); diff --git a/arch/powerpc/mm/book3s64/pkeys.c b/arch/powerpc/mm/book3s64/pkeys.c index 4a3aeddbe0c7..2b7ded396db4 100644 --- a/arch/powerpc/mm/book3s64/pkeys.c +++ b/arch/powerpc/mm/book3s64/pkeys.c @@ -185,6 +185,27 @@ void __init pkey_early_init_devtree(void) default_uamor &= ~(0x3ul << pkeyshift(execute_only_key)); } + if (unlikely(num_pkey <= 3)) { + /* + * Insufficient number of keys to support + * KUAP/KUEP feature. + */ + disable_kuep = true; + disable_kuap = true; + WARN(1, "Disabling kernel user protection due to low (%d) max supported keys\n", num_pkey); + } else { + /* handle key which is used by kernel for KAUP */ + reserved_allocation_mask |= (0x1 << 3); + /* + * Mark access for kup_key in default amr so that + * we continue to operate with that AMR in + * copy_to/from_user(). + */ + default_amr &= ~(0x3ul << pkeyshift(3)); + default_iamr &= ~(0x1ul << pkeyshift(3)); + default_uamor &= ~(0x3ul << pkeyshift(3)); + } + /* * Allow access for only key 0. And prevent any other modification. */ @@ -205,18 +226,6 @@ void __init pkey_early_init_devtree(void) reserved_allocation_mask |= (0x1 << 1); default_uamor &= ~(0x3ul << pkeyshift(1)); - /* handle key which is used by kernel for KAUP */ - reserved_allocation_mask |= (0x1 << 3); - /* - * Mark access for KUAP key in default amr so that - * we continue to operate with that AMR in - * copy_to/from_user(). - */ - default_amr &= ~(0x3ul << pkeyshift(3)); - default_iamr &= ~(0x1ul << pkeyshift(3)); - default_uamor &= ~(0x3ul << pkeyshift(3)); - - /* * Prevent the usage of OS reserved keys. Update UAMOR * for those keys. Also mark the rest of the bits in the diff --git a/arch/powerpc/mm/init-common.c b/arch/powerpc/mm/init-common.c index 8e0d792ac296..afdebb95bcae 100644 --- a/arch/powerpc/mm/init-common.c +++ b/arch/powerpc/mm/init-common.c @@ -28,8 +28,8 @@ EXPORT_SYMBOL_GPL(kernstart_addr); unsigned long kernstart_virt_addr __ro_after_init = KERNELBASE; EXPORT_SYMBOL_GPL(kernstart_virt_addr); -static bool disable_kuep = !IS_ENABLED(CONFIG_PPC_KUEP); -static bool disable_kuap = !IS_ENABLED(CONFIG_PPC_KUAP); +bool disable_kuep = !IS_ENABLED(CONFIG_PPC_KUEP); +bool disable_kuap = !IS_ENABLED(CONFIG_PPC_KUAP); static int __init parse_nosmep(char *p) { |