2019-04-18 14:51:18 +08:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
#ifndef _ASM_POWERPC_KUP_H_
|
|
|
|
#define _ASM_POWERPC_KUP_H_
|
|
|
|
|
powerpc/kuap: Fix set direction in allow/prevent_user_access()
__builtin_constant_p() always return 0 for pointers, so on RADIX
we always end up opening both direction (by writing 0 in SPR29):
0000000000000170 <._copy_to_user>:
...
1b0: 4c 00 01 2c isync
1b4: 39 20 00 00 li r9,0
1b8: 7d 3d 03 a6 mtspr 29,r9
1bc: 4c 00 01 2c isync
1c0: 48 00 00 01 bl 1c0 <._copy_to_user+0x50>
1c0: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000220 <._copy_from_user>:
...
2ac: 4c 00 01 2c isync
2b0: 39 20 00 00 li r9,0
2b4: 7d 3d 03 a6 mtspr 29,r9
2b8: 4c 00 01 2c isync
2bc: 7f c5 f3 78 mr r5,r30
2c0: 7f 83 e3 78 mr r3,r28
2c4: 48 00 00 01 bl 2c4 <._copy_from_user+0xa4>
2c4: R_PPC64_REL24 .__copy_tofrom_user
...
Use an explicit parameter for direction selection, so that GCC
is able to see it is a constant:
00000000000001b0 <._copy_to_user>:
...
1f0: 4c 00 01 2c isync
1f4: 3d 20 40 00 lis r9,16384
1f8: 79 29 07 c6 rldicr r9,r9,32,31
1fc: 7d 3d 03 a6 mtspr 29,r9
200: 4c 00 01 2c isync
204: 48 00 00 01 bl 204 <._copy_to_user+0x54>
204: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000260 <._copy_from_user>:
...
2ec: 4c 00 01 2c isync
2f0: 39 20 ff ff li r9,-1
2f4: 79 29 00 04 rldicr r9,r9,0,0
2f8: 7d 3d 03 a6 mtspr 29,r9
2fc: 4c 00 01 2c isync
300: 7f c5 f3 78 mr r5,r30
304: 7f 83 e3 78 mr r3,r28
308: 48 00 00 01 bl 308 <._copy_from_user+0xa8>
308: R_PPC64_REL24 .__copy_tofrom_user
...
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Spell out the directions, s/KUAP_R/KUAP_READ/ etc.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/f4e88ec4941d5facb35ce75026b0112f980086c3.1579866752.git.christophe.leroy@c-s.fr
2020-01-24 19:54:41 +08:00
|
|
|
#define KUAP_READ 1
|
|
|
|
#define KUAP_WRITE 2
|
|
|
|
#define KUAP_READ_WRITE (KUAP_READ | KUAP_WRITE)
|
|
|
|
|
2020-11-19 20:43:53 +08:00
|
|
|
#ifdef CONFIG_PPC_BOOK3S_64
|
2020-11-27 12:44:07 +08:00
|
|
|
#include <asm/book3s/64/kup.h>
|
2019-04-18 14:51:24 +08:00
|
|
|
#endif
|
2020-11-27 12:44:07 +08:00
|
|
|
|
2019-03-11 16:30:34 +08:00
|
|
|
#ifdef CONFIG_PPC_8xx
|
|
|
|
#include <asm/nohash/32/kup-8xx.h>
|
|
|
|
#endif
|
2020-11-27 12:44:07 +08:00
|
|
|
|
2021-10-19 15:29:28 +08:00
|
|
|
#ifdef CONFIG_BOOKE_OR_40x
|
|
|
|
#include <asm/nohash/kup-booke.h>
|
|
|
|
#endif
|
|
|
|
|
2019-03-11 16:30:35 +08:00
|
|
|
#ifdef CONFIG_PPC_BOOK3S_32
|
|
|
|
#include <asm/book3s/32/kup.h>
|
|
|
|
#endif
|
2019-04-18 14:51:24 +08:00
|
|
|
|
2019-03-11 16:30:31 +08:00
|
|
|
#ifdef __ASSEMBLY__
|
|
|
|
#ifndef CONFIG_PPC_KUAP
|
2020-11-19 20:43:53 +08:00
|
|
|
.macro kuap_check_amr gpr1, gpr2
|
|
|
|
.endm
|
|
|
|
|
2019-03-11 16:30:31 +08:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#else /* !__ASSEMBLY__ */
|
2019-04-18 14:51:18 +08:00
|
|
|
|
2020-12-02 12:38:54 +08:00
|
|
|
extern bool disable_kuep;
|
|
|
|
extern bool disable_kuap;
|
|
|
|
|
2020-06-09 12:32:38 +08:00
|
|
|
#include <linux/pgtable.h>
|
2019-04-18 14:51:20 +08:00
|
|
|
|
2021-10-19 15:29:12 +08:00
|
|
|
void setup_kup(void);
|
2019-04-18 14:51:19 +08:00
|
|
|
void setup_kuep(bool disabled);
|
|
|
|
|
2019-04-18 14:51:20 +08:00
|
|
|
#ifdef CONFIG_PPC_KUAP
|
|
|
|
void setup_kuap(bool disabled);
|
|
|
|
#else
|
|
|
|
static inline void setup_kuap(bool disabled) { }
|
2020-11-17 13:59:13 +08:00
|
|
|
|
2021-10-19 15:29:21 +08:00
|
|
|
static __always_inline bool kuap_is_disabled(void) { return true; }
|
|
|
|
|
2020-12-08 11:15:39 +08:00
|
|
|
static inline bool
|
2021-10-19 15:29:20 +08:00
|
|
|
__bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
|
2020-11-17 13:59:13 +08:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-10-19 15:29:23 +08:00
|
|
|
static inline void __kuap_lock(void) { }
|
2021-10-19 15:29:20 +08:00
|
|
|
static inline void __kuap_save_and_lock(struct pt_regs *regs) { }
|
2021-03-12 20:50:48 +08:00
|
|
|
static inline void kuap_user_restore(struct pt_regs *regs) { }
|
2021-10-19 15:29:20 +08:00
|
|
|
static inline void __kuap_kernel_restore(struct pt_regs *regs, unsigned long amr) { }
|
2021-03-12 20:50:48 +08:00
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
static inline unsigned long __kuap_get_and_assert_locked(void)
|
2021-03-12 20:50:48 +08:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
2020-11-19 20:43:53 +08:00
|
|
|
|
2020-11-17 13:59:13 +08:00
|
|
|
/*
|
|
|
|
* book3s/64/kup-radix.h defines these functions for the !KUAP case to flush
|
|
|
|
* the L1D cache after user accesses. Only include the empty stubs for other
|
|
|
|
* platforms.
|
|
|
|
*/
|
2020-11-19 20:43:53 +08:00
|
|
|
#ifndef CONFIG_PPC_BOOK3S_64
|
2021-10-19 15:29:20 +08:00
|
|
|
static inline void __allow_user_access(void __user *to, const void __user *from,
|
|
|
|
unsigned long size, unsigned long dir) { }
|
|
|
|
static inline void __prevent_user_access(unsigned long dir) { }
|
|
|
|
static inline unsigned long __prevent_user_access_return(void) { return 0UL; }
|
|
|
|
static inline void __restore_user_access(unsigned long flags) { }
|
2020-11-19 20:43:53 +08:00
|
|
|
#endif /* CONFIG_PPC_BOOK3S_64 */
|
2019-04-18 14:51:20 +08:00
|
|
|
#endif /* CONFIG_PPC_KUAP */
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
static __always_inline bool
|
|
|
|
bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
|
|
|
|
{
|
2021-10-19 15:29:21 +08:00
|
|
|
if (kuap_is_disabled())
|
|
|
|
return false;
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
return __bad_kuap_fault(regs, address, is_write);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __always_inline void kuap_assert_locked(void)
|
|
|
|
{
|
2021-10-19 15:29:21 +08:00
|
|
|
if (kuap_is_disabled())
|
|
|
|
return;
|
|
|
|
|
2021-10-19 15:29:22 +08:00
|
|
|
if (IS_ENABLED(CONFIG_PPC_KUAP_DEBUG))
|
|
|
|
__kuap_get_and_assert_locked();
|
2021-10-19 15:29:20 +08:00
|
|
|
}
|
|
|
|
|
2021-10-19 15:29:23 +08:00
|
|
|
static __always_inline void kuap_lock(void)
|
|
|
|
{
|
|
|
|
if (kuap_is_disabled())
|
|
|
|
return;
|
|
|
|
|
|
|
|
__kuap_lock();
|
|
|
|
}
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
static __always_inline void kuap_save_and_lock(struct pt_regs *regs)
|
|
|
|
{
|
2021-10-19 15:29:21 +08:00
|
|
|
if (kuap_is_disabled())
|
|
|
|
return;
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
__kuap_save_and_lock(regs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __always_inline void kuap_kernel_restore(struct pt_regs *regs, unsigned long amr)
|
|
|
|
{
|
2021-10-19 15:29:21 +08:00
|
|
|
if (kuap_is_disabled())
|
|
|
|
return;
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
__kuap_kernel_restore(regs, amr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __always_inline unsigned long kuap_get_and_assert_locked(void)
|
|
|
|
{
|
2021-10-19 15:29:21 +08:00
|
|
|
if (kuap_is_disabled())
|
|
|
|
return 0;
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
return __kuap_get_and_assert_locked();
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef CONFIG_PPC_BOOK3S_64
|
|
|
|
static __always_inline void allow_user_access(void __user *to, const void __user *from,
|
|
|
|
unsigned long size, unsigned long dir)
|
|
|
|
{
|
2021-10-19 15:29:21 +08:00
|
|
|
if (kuap_is_disabled())
|
|
|
|
return;
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
__allow_user_access(to, from, size, dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __always_inline void prevent_user_access(unsigned long dir)
|
|
|
|
{
|
2021-10-19 15:29:21 +08:00
|
|
|
if (kuap_is_disabled())
|
|
|
|
return;
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
__prevent_user_access(dir);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __always_inline unsigned long prevent_user_access_return(void)
|
|
|
|
{
|
2021-10-19 15:29:21 +08:00
|
|
|
if (kuap_is_disabled())
|
|
|
|
return 0;
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
return __prevent_user_access_return();
|
|
|
|
}
|
|
|
|
|
|
|
|
static __always_inline void restore_user_access(unsigned long flags)
|
|
|
|
{
|
2021-10-19 15:29:21 +08:00
|
|
|
if (kuap_is_disabled())
|
|
|
|
return;
|
|
|
|
|
2021-10-19 15:29:20 +08:00
|
|
|
__restore_user_access(flags);
|
|
|
|
}
|
|
|
|
#endif /* CONFIG_PPC_BOOK3S_64 */
|
|
|
|
|
2021-06-03 17:13:54 +08:00
|
|
|
static __always_inline void allow_read_from_user(const void __user *from, unsigned long size)
|
2019-04-18 14:51:20 +08:00
|
|
|
{
|
2021-02-07 18:08:11 +08:00
|
|
|
barrier_nospec();
|
powerpc/kuap: Fix set direction in allow/prevent_user_access()
__builtin_constant_p() always return 0 for pointers, so on RADIX
we always end up opening both direction (by writing 0 in SPR29):
0000000000000170 <._copy_to_user>:
...
1b0: 4c 00 01 2c isync
1b4: 39 20 00 00 li r9,0
1b8: 7d 3d 03 a6 mtspr 29,r9
1bc: 4c 00 01 2c isync
1c0: 48 00 00 01 bl 1c0 <._copy_to_user+0x50>
1c0: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000220 <._copy_from_user>:
...
2ac: 4c 00 01 2c isync
2b0: 39 20 00 00 li r9,0
2b4: 7d 3d 03 a6 mtspr 29,r9
2b8: 4c 00 01 2c isync
2bc: 7f c5 f3 78 mr r5,r30
2c0: 7f 83 e3 78 mr r3,r28
2c4: 48 00 00 01 bl 2c4 <._copy_from_user+0xa4>
2c4: R_PPC64_REL24 .__copy_tofrom_user
...
Use an explicit parameter for direction selection, so that GCC
is able to see it is a constant:
00000000000001b0 <._copy_to_user>:
...
1f0: 4c 00 01 2c isync
1f4: 3d 20 40 00 lis r9,16384
1f8: 79 29 07 c6 rldicr r9,r9,32,31
1fc: 7d 3d 03 a6 mtspr 29,r9
200: 4c 00 01 2c isync
204: 48 00 00 01 bl 204 <._copy_to_user+0x54>
204: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000260 <._copy_from_user>:
...
2ec: 4c 00 01 2c isync
2f0: 39 20 ff ff li r9,-1
2f4: 79 29 00 04 rldicr r9,r9,0,0
2f8: 7d 3d 03 a6 mtspr 29,r9
2fc: 4c 00 01 2c isync
300: 7f c5 f3 78 mr r5,r30
304: 7f 83 e3 78 mr r3,r28
308: 48 00 00 01 bl 308 <._copy_from_user+0xa8>
308: R_PPC64_REL24 .__copy_tofrom_user
...
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Spell out the directions, s/KUAP_R/KUAP_READ/ etc.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/f4e88ec4941d5facb35ce75026b0112f980086c3.1579866752.git.christophe.leroy@c-s.fr
2020-01-24 19:54:41 +08:00
|
|
|
allow_user_access(NULL, from, size, KUAP_READ);
|
2019-04-18 14:51:20 +08:00
|
|
|
}
|
|
|
|
|
2021-06-03 17:13:54 +08:00
|
|
|
static __always_inline void allow_write_to_user(void __user *to, unsigned long size)
|
2019-04-18 14:51:20 +08:00
|
|
|
{
|
powerpc/kuap: Fix set direction in allow/prevent_user_access()
__builtin_constant_p() always return 0 for pointers, so on RADIX
we always end up opening both direction (by writing 0 in SPR29):
0000000000000170 <._copy_to_user>:
...
1b0: 4c 00 01 2c isync
1b4: 39 20 00 00 li r9,0
1b8: 7d 3d 03 a6 mtspr 29,r9
1bc: 4c 00 01 2c isync
1c0: 48 00 00 01 bl 1c0 <._copy_to_user+0x50>
1c0: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000220 <._copy_from_user>:
...
2ac: 4c 00 01 2c isync
2b0: 39 20 00 00 li r9,0
2b4: 7d 3d 03 a6 mtspr 29,r9
2b8: 4c 00 01 2c isync
2bc: 7f c5 f3 78 mr r5,r30
2c0: 7f 83 e3 78 mr r3,r28
2c4: 48 00 00 01 bl 2c4 <._copy_from_user+0xa4>
2c4: R_PPC64_REL24 .__copy_tofrom_user
...
Use an explicit parameter for direction selection, so that GCC
is able to see it is a constant:
00000000000001b0 <._copy_to_user>:
...
1f0: 4c 00 01 2c isync
1f4: 3d 20 40 00 lis r9,16384
1f8: 79 29 07 c6 rldicr r9,r9,32,31
1fc: 7d 3d 03 a6 mtspr 29,r9
200: 4c 00 01 2c isync
204: 48 00 00 01 bl 204 <._copy_to_user+0x54>
204: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000260 <._copy_from_user>:
...
2ec: 4c 00 01 2c isync
2f0: 39 20 ff ff li r9,-1
2f4: 79 29 00 04 rldicr r9,r9,0,0
2f8: 7d 3d 03 a6 mtspr 29,r9
2fc: 4c 00 01 2c isync
300: 7f c5 f3 78 mr r5,r30
304: 7f 83 e3 78 mr r3,r28
308: 48 00 00 01 bl 308 <._copy_from_user+0xa8>
308: R_PPC64_REL24 .__copy_tofrom_user
...
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Spell out the directions, s/KUAP_R/KUAP_READ/ etc.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/f4e88ec4941d5facb35ce75026b0112f980086c3.1579866752.git.christophe.leroy@c-s.fr
2020-01-24 19:54:41 +08:00
|
|
|
allow_user_access(to, NULL, size, KUAP_WRITE);
|
|
|
|
}
|
|
|
|
|
2021-06-03 17:13:54 +08:00
|
|
|
static __always_inline void allow_read_write_user(void __user *to, const void __user *from,
|
|
|
|
unsigned long size)
|
powerpc/kuap: Fix set direction in allow/prevent_user_access()
__builtin_constant_p() always return 0 for pointers, so on RADIX
we always end up opening both direction (by writing 0 in SPR29):
0000000000000170 <._copy_to_user>:
...
1b0: 4c 00 01 2c isync
1b4: 39 20 00 00 li r9,0
1b8: 7d 3d 03 a6 mtspr 29,r9
1bc: 4c 00 01 2c isync
1c0: 48 00 00 01 bl 1c0 <._copy_to_user+0x50>
1c0: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000220 <._copy_from_user>:
...
2ac: 4c 00 01 2c isync
2b0: 39 20 00 00 li r9,0
2b4: 7d 3d 03 a6 mtspr 29,r9
2b8: 4c 00 01 2c isync
2bc: 7f c5 f3 78 mr r5,r30
2c0: 7f 83 e3 78 mr r3,r28
2c4: 48 00 00 01 bl 2c4 <._copy_from_user+0xa4>
2c4: R_PPC64_REL24 .__copy_tofrom_user
...
Use an explicit parameter for direction selection, so that GCC
is able to see it is a constant:
00000000000001b0 <._copy_to_user>:
...
1f0: 4c 00 01 2c isync
1f4: 3d 20 40 00 lis r9,16384
1f8: 79 29 07 c6 rldicr r9,r9,32,31
1fc: 7d 3d 03 a6 mtspr 29,r9
200: 4c 00 01 2c isync
204: 48 00 00 01 bl 204 <._copy_to_user+0x54>
204: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000260 <._copy_from_user>:
...
2ec: 4c 00 01 2c isync
2f0: 39 20 ff ff li r9,-1
2f4: 79 29 00 04 rldicr r9,r9,0,0
2f8: 7d 3d 03 a6 mtspr 29,r9
2fc: 4c 00 01 2c isync
300: 7f c5 f3 78 mr r5,r30
304: 7f 83 e3 78 mr r3,r28
308: 48 00 00 01 bl 308 <._copy_from_user+0xa8>
308: R_PPC64_REL24 .__copy_tofrom_user
...
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Spell out the directions, s/KUAP_R/KUAP_READ/ etc.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/f4e88ec4941d5facb35ce75026b0112f980086c3.1579866752.git.christophe.leroy@c-s.fr
2020-01-24 19:54:41 +08:00
|
|
|
{
|
2021-02-07 18:08:11 +08:00
|
|
|
barrier_nospec();
|
powerpc/kuap: Fix set direction in allow/prevent_user_access()
__builtin_constant_p() always return 0 for pointers, so on RADIX
we always end up opening both direction (by writing 0 in SPR29):
0000000000000170 <._copy_to_user>:
...
1b0: 4c 00 01 2c isync
1b4: 39 20 00 00 li r9,0
1b8: 7d 3d 03 a6 mtspr 29,r9
1bc: 4c 00 01 2c isync
1c0: 48 00 00 01 bl 1c0 <._copy_to_user+0x50>
1c0: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000220 <._copy_from_user>:
...
2ac: 4c 00 01 2c isync
2b0: 39 20 00 00 li r9,0
2b4: 7d 3d 03 a6 mtspr 29,r9
2b8: 4c 00 01 2c isync
2bc: 7f c5 f3 78 mr r5,r30
2c0: 7f 83 e3 78 mr r3,r28
2c4: 48 00 00 01 bl 2c4 <._copy_from_user+0xa4>
2c4: R_PPC64_REL24 .__copy_tofrom_user
...
Use an explicit parameter for direction selection, so that GCC
is able to see it is a constant:
00000000000001b0 <._copy_to_user>:
...
1f0: 4c 00 01 2c isync
1f4: 3d 20 40 00 lis r9,16384
1f8: 79 29 07 c6 rldicr r9,r9,32,31
1fc: 7d 3d 03 a6 mtspr 29,r9
200: 4c 00 01 2c isync
204: 48 00 00 01 bl 204 <._copy_to_user+0x54>
204: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000260 <._copy_from_user>:
...
2ec: 4c 00 01 2c isync
2f0: 39 20 ff ff li r9,-1
2f4: 79 29 00 04 rldicr r9,r9,0,0
2f8: 7d 3d 03 a6 mtspr 29,r9
2fc: 4c 00 01 2c isync
300: 7f c5 f3 78 mr r5,r30
304: 7f 83 e3 78 mr r3,r28
308: 48 00 00 01 bl 308 <._copy_from_user+0xa8>
308: R_PPC64_REL24 .__copy_tofrom_user
...
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Spell out the directions, s/KUAP_R/KUAP_READ/ etc.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/f4e88ec4941d5facb35ce75026b0112f980086c3.1579866752.git.christophe.leroy@c-s.fr
2020-01-24 19:54:41 +08:00
|
|
|
allow_user_access(to, from, size, KUAP_READ_WRITE);
|
2019-04-18 14:51:20 +08:00
|
|
|
}
|
|
|
|
|
2021-06-03 17:13:54 +08:00
|
|
|
static __always_inline void prevent_read_from_user(const void __user *from, unsigned long size)
|
2019-04-18 14:51:20 +08:00
|
|
|
{
|
2021-06-03 16:41:48 +08:00
|
|
|
prevent_user_access(KUAP_READ);
|
2019-04-18 14:51:20 +08:00
|
|
|
}
|
|
|
|
|
2021-06-03 17:13:54 +08:00
|
|
|
static __always_inline void prevent_write_to_user(void __user *to, unsigned long size)
|
2019-04-18 14:51:20 +08:00
|
|
|
{
|
2021-06-03 16:41:48 +08:00
|
|
|
prevent_user_access(KUAP_WRITE);
|
powerpc/kuap: Fix set direction in allow/prevent_user_access()
__builtin_constant_p() always return 0 for pointers, so on RADIX
we always end up opening both direction (by writing 0 in SPR29):
0000000000000170 <._copy_to_user>:
...
1b0: 4c 00 01 2c isync
1b4: 39 20 00 00 li r9,0
1b8: 7d 3d 03 a6 mtspr 29,r9
1bc: 4c 00 01 2c isync
1c0: 48 00 00 01 bl 1c0 <._copy_to_user+0x50>
1c0: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000220 <._copy_from_user>:
...
2ac: 4c 00 01 2c isync
2b0: 39 20 00 00 li r9,0
2b4: 7d 3d 03 a6 mtspr 29,r9
2b8: 4c 00 01 2c isync
2bc: 7f c5 f3 78 mr r5,r30
2c0: 7f 83 e3 78 mr r3,r28
2c4: 48 00 00 01 bl 2c4 <._copy_from_user+0xa4>
2c4: R_PPC64_REL24 .__copy_tofrom_user
...
Use an explicit parameter for direction selection, so that GCC
is able to see it is a constant:
00000000000001b0 <._copy_to_user>:
...
1f0: 4c 00 01 2c isync
1f4: 3d 20 40 00 lis r9,16384
1f8: 79 29 07 c6 rldicr r9,r9,32,31
1fc: 7d 3d 03 a6 mtspr 29,r9
200: 4c 00 01 2c isync
204: 48 00 00 01 bl 204 <._copy_to_user+0x54>
204: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000260 <._copy_from_user>:
...
2ec: 4c 00 01 2c isync
2f0: 39 20 ff ff li r9,-1
2f4: 79 29 00 04 rldicr r9,r9,0,0
2f8: 7d 3d 03 a6 mtspr 29,r9
2fc: 4c 00 01 2c isync
300: 7f c5 f3 78 mr r5,r30
304: 7f 83 e3 78 mr r3,r28
308: 48 00 00 01 bl 308 <._copy_from_user+0xa8>
308: R_PPC64_REL24 .__copy_tofrom_user
...
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Spell out the directions, s/KUAP_R/KUAP_READ/ etc.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/f4e88ec4941d5facb35ce75026b0112f980086c3.1579866752.git.christophe.leroy@c-s.fr
2020-01-24 19:54:41 +08:00
|
|
|
}
|
|
|
|
|
2021-06-03 17:13:54 +08:00
|
|
|
static __always_inline void prevent_read_write_user(void __user *to, const void __user *from,
|
|
|
|
unsigned long size)
|
powerpc/kuap: Fix set direction in allow/prevent_user_access()
__builtin_constant_p() always return 0 for pointers, so on RADIX
we always end up opening both direction (by writing 0 in SPR29):
0000000000000170 <._copy_to_user>:
...
1b0: 4c 00 01 2c isync
1b4: 39 20 00 00 li r9,0
1b8: 7d 3d 03 a6 mtspr 29,r9
1bc: 4c 00 01 2c isync
1c0: 48 00 00 01 bl 1c0 <._copy_to_user+0x50>
1c0: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000220 <._copy_from_user>:
...
2ac: 4c 00 01 2c isync
2b0: 39 20 00 00 li r9,0
2b4: 7d 3d 03 a6 mtspr 29,r9
2b8: 4c 00 01 2c isync
2bc: 7f c5 f3 78 mr r5,r30
2c0: 7f 83 e3 78 mr r3,r28
2c4: 48 00 00 01 bl 2c4 <._copy_from_user+0xa4>
2c4: R_PPC64_REL24 .__copy_tofrom_user
...
Use an explicit parameter for direction selection, so that GCC
is able to see it is a constant:
00000000000001b0 <._copy_to_user>:
...
1f0: 4c 00 01 2c isync
1f4: 3d 20 40 00 lis r9,16384
1f8: 79 29 07 c6 rldicr r9,r9,32,31
1fc: 7d 3d 03 a6 mtspr 29,r9
200: 4c 00 01 2c isync
204: 48 00 00 01 bl 204 <._copy_to_user+0x54>
204: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000260 <._copy_from_user>:
...
2ec: 4c 00 01 2c isync
2f0: 39 20 ff ff li r9,-1
2f4: 79 29 00 04 rldicr r9,r9,0,0
2f8: 7d 3d 03 a6 mtspr 29,r9
2fc: 4c 00 01 2c isync
300: 7f c5 f3 78 mr r5,r30
304: 7f 83 e3 78 mr r3,r28
308: 48 00 00 01 bl 308 <._copy_from_user+0xa8>
308: R_PPC64_REL24 .__copy_tofrom_user
...
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Spell out the directions, s/KUAP_R/KUAP_READ/ etc.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/f4e88ec4941d5facb35ce75026b0112f980086c3.1579866752.git.christophe.leroy@c-s.fr
2020-01-24 19:54:41 +08:00
|
|
|
{
|
2021-06-03 16:41:48 +08:00
|
|
|
prevent_user_access(KUAP_READ_WRITE);
|
2019-04-18 14:51:20 +08:00
|
|
|
}
|
|
|
|
|
2021-06-03 17:13:54 +08:00
|
|
|
static __always_inline void prevent_current_access_user(void)
|
2020-01-24 19:54:43 +08:00
|
|
|
{
|
2021-06-03 16:41:48 +08:00
|
|
|
prevent_user_access(KUAP_READ_WRITE);
|
2020-01-24 19:54:43 +08:00
|
|
|
}
|
|
|
|
|
2021-06-03 17:13:54 +08:00
|
|
|
static __always_inline void prevent_current_read_from_user(void)
|
2020-04-03 15:20:53 +08:00
|
|
|
{
|
2021-06-03 16:41:48 +08:00
|
|
|
prevent_user_access(KUAP_READ);
|
2020-04-03 15:20:53 +08:00
|
|
|
}
|
|
|
|
|
2021-06-03 17:13:54 +08:00
|
|
|
static __always_inline void prevent_current_write_to_user(void)
|
2020-04-03 15:20:53 +08:00
|
|
|
{
|
2021-06-03 16:41:48 +08:00
|
|
|
prevent_user_access(KUAP_WRITE);
|
2020-04-03 15:20:53 +08:00
|
|
|
}
|
|
|
|
|
2019-04-18 14:51:18 +08:00
|
|
|
#endif /* !__ASSEMBLY__ */
|
|
|
|
|
powerpc/kuap: Fix set direction in allow/prevent_user_access()
__builtin_constant_p() always return 0 for pointers, so on RADIX
we always end up opening both direction (by writing 0 in SPR29):
0000000000000170 <._copy_to_user>:
...
1b0: 4c 00 01 2c isync
1b4: 39 20 00 00 li r9,0
1b8: 7d 3d 03 a6 mtspr 29,r9
1bc: 4c 00 01 2c isync
1c0: 48 00 00 01 bl 1c0 <._copy_to_user+0x50>
1c0: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000220 <._copy_from_user>:
...
2ac: 4c 00 01 2c isync
2b0: 39 20 00 00 li r9,0
2b4: 7d 3d 03 a6 mtspr 29,r9
2b8: 4c 00 01 2c isync
2bc: 7f c5 f3 78 mr r5,r30
2c0: 7f 83 e3 78 mr r3,r28
2c4: 48 00 00 01 bl 2c4 <._copy_from_user+0xa4>
2c4: R_PPC64_REL24 .__copy_tofrom_user
...
Use an explicit parameter for direction selection, so that GCC
is able to see it is a constant:
00000000000001b0 <._copy_to_user>:
...
1f0: 4c 00 01 2c isync
1f4: 3d 20 40 00 lis r9,16384
1f8: 79 29 07 c6 rldicr r9,r9,32,31
1fc: 7d 3d 03 a6 mtspr 29,r9
200: 4c 00 01 2c isync
204: 48 00 00 01 bl 204 <._copy_to_user+0x54>
204: R_PPC64_REL24 .__copy_tofrom_user
...
0000000000000260 <._copy_from_user>:
...
2ec: 4c 00 01 2c isync
2f0: 39 20 ff ff li r9,-1
2f4: 79 29 00 04 rldicr r9,r9,0,0
2f8: 7d 3d 03 a6 mtspr 29,r9
2fc: 4c 00 01 2c isync
300: 7f c5 f3 78 mr r5,r30
304: 7f 83 e3 78 mr r3,r28
308: 48 00 00 01 bl 308 <._copy_from_user+0xa8>
308: R_PPC64_REL24 .__copy_tofrom_user
...
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Spell out the directions, s/KUAP_R/KUAP_READ/ etc.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/f4e88ec4941d5facb35ce75026b0112f980086c3.1579866752.git.christophe.leroy@c-s.fr
2020-01-24 19:54:41 +08:00
|
|
|
#endif /* _ASM_POWERPC_KUAP_H_ */
|