[PATCH v6 09/10] powerpc/64s: Implement KUAP for Radix MMU

Nicholas Piggin npiggin at gmail.com
Fri Apr 17 20:39:30 AEST 2020


Excerpts from Christophe Leroy's message of April 17, 2020 8:10 pm:
> 
> 
> Le 18/04/2019 à 08:51, Michael Ellerman a écrit :
>> Kernel Userspace Access Prevention utilises a feature of the Radix MMU
>> which disallows read and write access to userspace addresses. By
>> utilising this, the kernel is prevented from accessing user data from
>> outside of trusted paths that perform proper safety checks, such as
>> copy_{to/from}_user() and friends.
>> 
>> Userspace access is disabled from early boot and is only enabled when
>> performing an operation like copy_{to/from}_user(). The register that
>> controls this (AMR) does not prevent userspace from accessing itself,
>> so there is no need to save and restore when entering and exiting
>> userspace.
>> 
>> When entering the kernel from the kernel we save AMR and if it is not
>> blocking user access (because eg. we faulted doing a user access) we
>> reblock user access for the duration of the exception (ie. the page
>> fault) and then restore the AMR when returning back to the kernel.
>> 
>> This feature can be tested by using the lkdtm driver (CONFIG_LKDTM=y)
>> and performing the following:
>> 
>>    # (echo ACCESS_USERSPACE) > [debugfs]/provoke-crash/DIRECT
>> 
>> If enabled, this should send SIGSEGV to the thread.
>> 
>> We also add paranoid checking of AMR in switch and syscall return
>> under CONFIG_PPC_KUAP_DEBUG.
>> 
>> Co-authored-by: Michael Ellerman <mpe at ellerman.id.au>
>> Signed-off-by: Russell Currey <ruscur at russell.cc>
>> Signed-off-by: Michael Ellerman <mpe at ellerman.id.au>
> 
> [...]
> 
>> diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
>> index 15c67d2c0534..7cc25389c6bd 100644
>> --- a/arch/powerpc/kernel/entry_64.S
>> +++ b/arch/powerpc/kernel/entry_64.S
> 
> [...]
> 
>> @@ -594,6 +606,8 @@ _GLOBAL(_switch)
>>   	std	r23,_CCR(r1)
>>   	std	r1,KSP(r3)	/* Set old stack pointer */
>>   
>> +	kuap_check_amr r9, r10
>> +
>>   	FLUSH_COUNT_CACHE
>>   
>>   	/*
> 
> I'm having a problem with this check. As you know I implemented the 
> exact same check in _switch() in entry_32.S. After adding some printk 
> inside an user_access_begin()/user_access_end() section, I started to 
> get valid user accesses blocked by KUAP. Then I activated 
> CONFIG_PPC_KUAP_DEBUG which led me to WARNINGs on this check.
> 
> This is due to schedule() being called by printk() inside the section 
> where user access is unlocked. How is this supposed to work ? When 

Unlocked user access sections are supposed to be very constrained,
I think x86's objtool has a checker to verify nothing much gets
called. Printk shouldn't be.

I was hitting the same assertion and it was because the uaccess
macros were pulling lots of things into the user access region.

https://patchwork.ozlabs.org/project/linuxppc-dev/patch/20200407041245.600651-1-npiggin@gmail.com/

If that doesn't solve your problem... then now is printk being
called with user access enabled?

Thanks,
Nick


More information about the Linuxppc-dev mailing list