Skip to content

Commit

Permalink
powerpc/8xx: Add Kernel Userspace Access Protection
Browse files Browse the repository at this point in the history
This patch adds Kernel Userspace Access Protection on the 8xx.

When a page is RO or RW, it is set RO or RW for Key 0 and NA
for Key 1.

Up to now, the User group is defined with Key 0 for both User and
Supervisor.

By changing the group to Key 0 for User and Key 1 for Supervisor,
this patch prevents the Kernel from being able to access user data.

At exception entry, the kernel saves SPRN_MD_AP in the regs struct,
and reapply the protection. At exception exit it restores SPRN_MD_AP
with the value saved on exception entry.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
[mpe: Drop allow_read/write_to/from_user() as they're now in kup.h]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
  • Loading branch information
Christophe Leroy authored and Michael Ellerman committed Apr 21, 2019
1 parent 06fbe81 commit 2679f9b
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 0 deletions.
3 changes: 3 additions & 0 deletions arch/powerpc/include/asm/kup.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#ifdef CONFIG_PPC64
#include <asm/book3s/64/kup-radix.h>
#endif
#ifdef CONFIG_PPC_8xx
#include <asm/nohash/32/kup-8xx.h>
#endif

#ifdef __ASSEMBLY__
#ifndef CONFIG_PPC_KUAP
Expand Down
58 changes: 58 additions & 0 deletions arch/powerpc/include/asm/nohash/32/kup-8xx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_POWERPC_KUP_8XX_H_
#define _ASM_POWERPC_KUP_8XX_H_

#include <asm/bug.h>

#ifdef CONFIG_PPC_KUAP

#ifdef __ASSEMBLY__

.macro kuap_save_and_lock sp, thread, gpr1, gpr2, gpr3
lis \gpr2, MD_APG_KUAP@h /* only APG0 and APG1 are used */
mfspr \gpr1, SPRN_MD_AP
mtspr SPRN_MD_AP, \gpr2
stw \gpr1, STACK_REGS_KUAP(\sp)
.endm

.macro kuap_restore sp, current, gpr1, gpr2, gpr3
lwz \gpr1, STACK_REGS_KUAP(\sp)
mtspr SPRN_MD_AP, \gpr1
.endm

.macro kuap_check current, gpr
#ifdef CONFIG_PPC_KUAP_DEBUG
mfspr \gpr, SPRN_MD_AP
rlwinm \gpr, \gpr, 16, 0xffff
999: twnei \gpr, MD_APG_KUAP@h
EMIT_BUG_ENTRY 999b, __FILE__, __LINE__, (BUGFLAG_WARNING | BUGFLAG_ONCE)
#endif
.endm

#else /* !__ASSEMBLY__ */

#include <asm/reg.h>

static inline void allow_user_access(void __user *to, const void __user *from,
unsigned long size)
{
mtspr(SPRN_MD_AP, MD_APG_INIT);
}

static inline void prevent_user_access(void __user *to, const void __user *from,
unsigned long size)
{
mtspr(SPRN_MD_AP, MD_APG_KUAP);
}

static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write)
{
return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000),
"Bug: fault blocked by AP register !");
}

#endif /* !__ASSEMBLY__ */

#endif /* CONFIG_PPC_KUAP */

#endif /* _ASM_POWERPC_KUP_8XX_H_ */
7 changes: 7 additions & 0 deletions arch/powerpc/include/asm/nohash/32/mmu-8xx.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@
*/
#define MD_APG_INIT 0x4fffffff

/*
* 0 => No user => 01 (all accesses performed according to page definition)
* 1 => User => 10 (all accesses performed according to swaped page definition)
* 2-16 => NA => 11 (all accesses performed as user iaw page definition)
*/
#define MD_APG_KUAP 0x6fffffff

/* The effective page number register. When read, contains the information
* about the last instruction TLB miss. When MD_RPN is written, bits in
* this register are used to create the TLB entry.
Expand Down
12 changes: 12 additions & 0 deletions arch/powerpc/mm/8xx_mmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,3 +225,15 @@ void __init setup_kuep(bool disabled)
mtspr(SPRN_MI_AP, MI_APG_KUEP);
}
#endif

#ifdef CONFIG_PPC_KUAP
void __init setup_kuap(bool disabled)
{
pr_info("Activating Kernel Userspace Access Protection\n");

if (disabled)
pr_warn("KUAP cannot be disabled yet on 8xx when compiled in\n");

mtspr(SPRN_MD_AP, MD_APG_KUAP);
}
#endif
1 change: 1 addition & 0 deletions arch/powerpc/platforms/Kconfig.cputype
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ config PPC_8xx
select FSL_SOC
select SYS_SUPPORTS_HUGETLBFS
select PPC_HAVE_KUEP
select PPC_HAVE_KUAP

config 40x
bool "AMCC 40x"
Expand Down

0 comments on commit 2679f9b

Please sign in to comment.