mirror of https://gitee.com/openkylin/linux.git
powerpc/book3s64/pkeys: Reset userspace AMR correctly on exec
On fork, we inherit from the parent and on exec, we should switch to default_amr values. Also, avoid changing the AMR register value within the kernel. The kernel now runs with different AMR values. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Reviewed-by: Sandipan Das <sandipan@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://lore.kernel.org/r/20201127044424.40686-13-aneesh.kumar@linux.ibm.com
This commit is contained in:
parent
f643fcab74
commit
d5fa30e699
|
@ -6,6 +6,8 @@
|
||||||
#include <asm/book3s/64/hash-pkey.h>
|
#include <asm/book3s/64/hash-pkey.h>
|
||||||
|
|
||||||
extern u64 __ro_after_init default_uamor;
|
extern u64 __ro_after_init default_uamor;
|
||||||
|
extern u64 __ro_after_init default_amr;
|
||||||
|
extern u64 __ro_after_init default_iamr;
|
||||||
|
|
||||||
static inline u64 vmflag_to_pte_pkey_bits(u64 vm_flags)
|
static inline u64 vmflag_to_pte_pkey_bits(u64 vm_flags)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1546,6 +1546,11 @@ void arch_setup_new_exec(void)
|
||||||
struct pt_regs *regs = task_stack_page(current) + THREAD_SIZE;
|
struct pt_regs *regs = task_stack_page(current) + THREAD_SIZE;
|
||||||
current->thread.regs = regs - 1;
|
current->thread.regs = regs - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PPC_MEM_KEYS
|
||||||
|
current->thread.regs->amr = default_amr;
|
||||||
|
current->thread.regs->iamr = default_iamr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
|
@ -1895,7 +1900,6 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
|
||||||
current->thread.load_tm = 0;
|
current->thread.load_tm = 0;
|
||||||
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
|
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
|
||||||
|
|
||||||
thread_pkey_regs_init(¤t->thread);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(start_thread);
|
EXPORT_SYMBOL(start_thread);
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ static u32 initial_allocation_mask __ro_after_init;
|
||||||
* Even if we allocate keys with sys_pkey_alloc(), we need to make sure
|
* Even if we allocate keys with sys_pkey_alloc(), we need to make sure
|
||||||
* other thread still find the access denied using the same keys.
|
* other thread still find the access denied using the same keys.
|
||||||
*/
|
*/
|
||||||
static u64 default_amr = ~0x0UL;
|
u64 default_amr __ro_after_init = ~0x0UL;
|
||||||
static u64 default_iamr = 0x5555555555555555UL;
|
u64 default_iamr __ro_after_init = 0x5555555555555555UL;
|
||||||
u64 default_uamor __ro_after_init;
|
u64 default_uamor __ro_after_init;
|
||||||
/*
|
/*
|
||||||
* Key used to implement PROT_EXEC mmap. Denies READ/WRITE
|
* Key used to implement PROT_EXEC mmap. Denies READ/WRITE
|
||||||
|
@ -396,18 +396,6 @@ void thread_pkey_regs_restore(struct thread_struct *new_thread,
|
||||||
write_iamr(new_thread->iamr);
|
write_iamr(new_thread->iamr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void thread_pkey_regs_init(struct thread_struct *thread)
|
|
||||||
{
|
|
||||||
if (!mmu_has_feature(MMU_FTR_PKEY))
|
|
||||||
return;
|
|
||||||
|
|
||||||
thread->amr = default_amr;
|
|
||||||
thread->iamr = default_iamr;
|
|
||||||
|
|
||||||
write_amr(default_amr);
|
|
||||||
write_iamr(default_iamr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int execute_only_pkey(struct mm_struct *mm)
|
int execute_only_pkey(struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
return mm->context.execute_only_pkey;
|
return mm->context.execute_only_pkey;
|
||||||
|
|
Loading…
Reference in New Issue