powerpc/book3s64/kup: Check max key supported before enabling kup
authorAneesh Kumar K.V <aneesh.kumar@linux.ibm.com>
Wed, 2 Dec 2020 04:38:54 +0000 (10:08 +0530)
committerMichael Ellerman <mpe@ellerman.id.au>
Thu, 3 Dec 2020 14:01:27 +0000 (01:01 +1100)
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
arch/powerpc/include/asm/kup.h
arch/powerpc/mm/book3s64/pkeys.c
arch/powerpc/mm/init-common.c

index 952be0414f433b578a6d288bd6948b73e8c08040..f8ec679bd2de7055b1f1b72d7c256cf7abfb61a2 100644 (file)
@@ -44,6 +44,9 @@
 
 #else /* !__ASSEMBLY__ */
 
+extern bool disable_kuep;
+extern bool disable_kuap;
+
 #include <linux/pgtable.h>
 
 void setup_kup(void);
index 4a3aeddbe0c7e2fd207ec9189108834c1c5f8fef..2b7ded396db4db89561aa322f2ba54e3cea39c57 100644 (file)
@@ -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
index 8e0d792ac2967c029f1c29a6254d953e92342771..afdebb95bcae151366c24af780a198c12bdcb1fc 100644 (file)
@@ -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)
 {