9
9
10
10
#include <linux/jump_label.h>
11
11
12
+ extern struct static_key_false disable_kuap_key ;
12
13
extern struct static_key_false disable_kuep_key ;
13
14
14
15
static __always_inline bool kuap_is_disabled (void )
15
16
{
16
- return !IS_ENABLED (CONFIG_PPC_KUAP );
17
+ return !IS_ENABLED (CONFIG_PPC_KUAP ) || static_branch_unlikely ( & disable_kuap_key ) ;
17
18
}
18
19
19
20
static __always_inline bool kuep_is_disabled (void )
@@ -62,6 +63,9 @@ static inline void kuap_save_and_lock(struct pt_regs *regs)
62
63
u32 addr = kuap & 0xf0000000 ;
63
64
u32 end = kuap << 28 ;
64
65
66
+ if (kuap_is_disabled ())
67
+ return ;
68
+
65
69
regs -> kuap = kuap ;
66
70
if (unlikely (!kuap ))
67
71
return ;
@@ -79,6 +83,9 @@ static inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long kuap)
79
83
u32 addr = regs -> kuap & 0xf0000000 ;
80
84
u32 end = regs -> kuap << 28 ;
81
85
86
+ if (kuap_is_disabled ())
87
+ return ;
88
+
82
89
current -> thread .kuap = regs -> kuap ;
83
90
84
91
if (unlikely (regs -> kuap == kuap ))
@@ -91,6 +98,9 @@ static inline unsigned long kuap_get_and_assert_locked(void)
91
98
{
92
99
unsigned long kuap = current -> thread .kuap ;
93
100
101
+ if (kuap_is_disabled ())
102
+ return 0 ;
103
+
94
104
WARN_ON_ONCE (IS_ENABLED (CONFIG_PPC_KUAP_DEBUG ) && kuap != 0 );
95
105
96
106
return kuap ;
@@ -106,6 +116,9 @@ static __always_inline void allow_user_access(void __user *to, const void __user
106
116
{
107
117
u32 addr , end ;
108
118
119
+ if (kuap_is_disabled ())
120
+ return ;
121
+
109
122
BUILD_BUG_ON (!__builtin_constant_p (dir ));
110
123
BUILD_BUG_ON (dir & ~KUAP_READ_WRITE );
111
124
@@ -128,6 +141,9 @@ static __always_inline void prevent_user_access(void __user *to, const void __us
128
141
{
129
142
u32 addr , end ;
130
143
144
+ if (kuap_is_disabled ())
145
+ return ;
146
+
131
147
BUILD_BUG_ON (!__builtin_constant_p (dir ));
132
148
133
149
if (dir & KUAP_CURRENT_WRITE ) {
@@ -159,6 +175,9 @@ static inline unsigned long prevent_user_access_return(void)
159
175
unsigned long end = flags << 28 ;
160
176
void __user * to = (__force void __user * )addr ;
161
177
178
+ if (kuap_is_disabled ())
179
+ return 0 ;
180
+
162
181
if (flags )
163
182
prevent_user_access (to , to , end - addr , KUAP_READ_WRITE );
164
183
@@ -171,6 +190,9 @@ static inline void restore_user_access(unsigned long flags)
171
190
unsigned long end = flags << 28 ;
172
191
void __user * to = (__force void __user * )addr ;
173
192
193
+ if (kuap_is_disabled ())
194
+ return ;
195
+
174
196
if (flags )
175
197
allow_user_access (to , to , end - addr , KUAP_READ_WRITE );
176
198
}
@@ -181,6 +203,9 @@ bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
181
203
unsigned long begin = regs -> kuap & 0xf0000000 ;
182
204
unsigned long end = regs -> kuap << 28 ;
183
205
206
+ if (kuap_is_disabled ())
207
+ return false;
208
+
184
209
return is_write && (address < begin || address >= end );
185
210
}
186
211
0 commit comments