Skip to content

Commit 6b4d630

Browse files
chleroympe
authored andcommitted
powerpc/32s: Allow disabling KUAP at boot time
PPC64 uses MMU features to enable/disable KUAP at boot time. But feature fixups are applied way too early on PPC32. Now that all KUAP related actions are in C following the conversion of KUAP initial setup and context switch in C, static branches can be used to enable/disable KUAP. Signed-off-by: Christophe Leroy <[email protected]> [mpe: Export disable_kuap_key to fix build errors] Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/cd79e8008455fba5395d099f9bb1305c039b931c.1622708530.git.christophe.leroy@csgroup.eu
1 parent 50d2f10 commit 6b4d630

File tree

2 files changed

+34
-5
lines changed
  • arch/powerpc

2 files changed

+34
-5
lines changed

arch/powerpc/include/asm/book3s/32/kup.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99

1010
#include <linux/jump_label.h>
1111

12+
extern struct static_key_false disable_kuap_key;
1213
extern struct static_key_false disable_kuep_key;
1314

1415
static __always_inline bool kuap_is_disabled(void)
1516
{
16-
return !IS_ENABLED(CONFIG_PPC_KUAP);
17+
return !IS_ENABLED(CONFIG_PPC_KUAP) || static_branch_unlikely(&disable_kuap_key);
1718
}
1819

1920
static __always_inline bool kuep_is_disabled(void)
@@ -62,6 +63,9 @@ static inline void kuap_save_and_lock(struct pt_regs *regs)
6263
u32 addr = kuap & 0xf0000000;
6364
u32 end = kuap << 28;
6465

66+
if (kuap_is_disabled())
67+
return;
68+
6569
regs->kuap = kuap;
6670
if (unlikely(!kuap))
6771
return;
@@ -79,6 +83,9 @@ static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
7983
u32 addr = regs->kuap & 0xf0000000;
8084
u32 end = regs->kuap << 28;
8185

86+
if (kuap_is_disabled())
87+
return;
88+
8289
current->thread.kuap = regs->kuap;
8390

8491
if (unlikely(regs->kuap == kuap))
@@ -91,6 +98,9 @@ static inline unsigned long kuap_get_and_assert_locked(void)
9198
{
9299
unsigned long kuap = current->thread.kuap;
93100

101+
if (kuap_is_disabled())
102+
return 0;
103+
94104
WARN_ON_ONCE(IS_ENABLED(CONFIG_PPC_KUAP_DEBUG) && kuap != 0);
95105

96106
return kuap;
@@ -106,6 +116,9 @@ static __always_inline void allow_user_access(void __user *to, const void __user
106116
{
107117
u32 addr, end;
108118

119+
if (kuap_is_disabled())
120+
return;
121+
109122
BUILD_BUG_ON(!__builtin_constant_p(dir));
110123
BUILD_BUG_ON(dir & ~KUAP_READ_WRITE);
111124

@@ -128,6 +141,9 @@ static __always_inline void prevent_user_access(void __user *to, const void __us
128141
{
129142
u32 addr, end;
130143

144+
if (kuap_is_disabled())
145+
return;
146+
131147
BUILD_BUG_ON(!__builtin_constant_p(dir));
132148

133149
if (dir & KUAP_CURRENT_WRITE) {
@@ -159,6 +175,9 @@ static inline unsigned long prevent_user_access_return(void)
159175
unsigned long end = flags << 28;
160176
void __user *to = (__force void __user *)addr;
161177

178+
if (kuap_is_disabled())
179+
return 0;
180+
162181
if (flags)
163182
prevent_user_access(to, to, end - addr, KUAP_READ_WRITE);
164183

@@ -171,6 +190,9 @@ static inline void restore_user_access(unsigned long flags)
171190
unsigned long end = flags << 28;
172191
void __user *to = (__force void __user *)addr;
173192

193+
if (kuap_is_disabled())
194+
return;
195+
174196
if (flags)
175197
allow_user_access(to, to, end - addr, KUAP_READ_WRITE);
176198
}
@@ -181,6 +203,9 @@ bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
181203
unsigned long begin = regs->kuap & 0xf0000000;
182204
unsigned long end = regs->kuap << 28;
183205

206+
if (kuap_is_disabled())
207+
return false;
208+
184209
return is_write && (address < begin || address >= end);
185210
}
186211

arch/powerpc/mm/book3s32/kuap.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,19 @@
33
#include <asm/kup.h>
44
#include <asm/smp.h>
55

6+
struct static_key_false disable_kuap_key;
7+
EXPORT_SYMBOL(disable_kuap_key);
8+
69
void __init setup_kuap(bool disabled)
710
{
8-
kuap_update_sr(mfsr(0) | SR_KS, 0, TASK_SIZE);
11+
if (!disabled)
12+
kuap_update_sr(mfsr(0) | SR_KS, 0, TASK_SIZE);
913

1014
if (smp_processor_id() != boot_cpuid)
1115
return;
1216

13-
pr_info("Activating Kernel Userspace Access Protection\n");
14-
1517
if (disabled)
16-
pr_warn("KUAP cannot be disabled yet on 6xx when compiled in\n");
18+
static_branch_enable(&disable_kuap_key);
19+
else
20+
pr_info("Activating Kernel Userspace Access Protection\n");
1721
}

0 commit comments

Comments
 (0)