diff mbox

[v4,0/3] arm64: usercopy: Implement stack frame object validation

Message ID 20170216182917.19637-1-james.morse@arm.com (mailing list archive)
State New, archived
Headers show

Commit Message

James Morse Feb. 16, 2017, 6:29 p.m. UTC
Hi all,

This version of Sahara's arch_within_stack_frames() series replaces the
open-coded stack walker with a call to arm64's existing walker.

Patch 2 can be tested independently with this change[0].

lkdtm's use of unallocated stack regions is a separate problem, patch 3
tries to address this.

Sahara, it would be good to get your review of this!
I'm afraid I omitted your patch-3 as it stopped the lkdtm test from working,
I suspect its not tricking the compiler, but I haven't investigated.


Thanks,

James

[0] Change to lkdtm to generate accesses that overlap stack frames.
--------------%<--------------
--------------%<--------------


James Morse (2):
  arm64: Add arch_within_stack_frames() for hardened usercopy
  arm64/uaccess: Add hardened usercopy check for bad stack accesses

Sahara (1):
  usercopy: create enum stack_type

 arch/arm64/Kconfig                   |  1 +
 arch/arm64/include/asm/thread_info.h |  7 ++++-
 arch/arm64/include/asm/uaccess.h     | 20 +++++++++++++
 arch/arm64/kernel/stacktrace.c       | 54 ++++++++++++++++++++++++++++++++++--
 arch/x86/include/asm/thread_info.h   | 19 +++++++------
 include/linux/thread_info.h          | 13 +++++++--
 mm/usercopy.c                        |  8 +-----
 7 files changed, 99 insertions(+), 23 deletions(-)

Comments

Kees Cook Feb. 17, 2017, 12:54 a.m. UTC | #1
On Thu, Feb 16, 2017 at 10:29 AM, James Morse <james.morse@arm.com> wrote:
> Hi all,
>
> This version of Sahara's arch_within_stack_frames() series replaces the
> open-coded stack walker with a call to arm64's existing walker.
>
> Patch 2 can be tested independently with this change[0].
>
> lkdtm's use of unallocated stack regions is a separate problem, patch 3
> tries to address this.
>
> Sahara, it would be good to get your review of this!
> I'm afraid I omitted your patch-3 as it stopped the lkdtm test from working,
> I suspect its not tricking the compiler, but I haven't investigated.
>
>
> Thanks,
>
> James
>
> [0] Change to lkdtm to generate accesses that overlap stack frames.
> --------------%<--------------
> diff --git a/drivers/misc/lkdtm_usercopy.c b/drivers/misc/lkdtm_usercopy.c
> index 1dd611423d8b..fcbba3a14387 100644
> --- a/drivers/misc/lkdtm_usercopy.c
> +++ b/drivers/misc/lkdtm_usercopy.c
> @@ -57,7 +57,8 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame)
>
>         /* This is a pointer to outside our current stack frame. */
>         if (bad_frame) {
> -               bad_stack = do_usercopy_stack_callee((uintptr_t)&bad_stack);
> +               bad_stack = __builtin_frame_address(0);
> +               bad_stack -= sizeof(good_stack)/2;

Ah, sneaky, yeah, that'll work nicely.

(Though it should likely get wrapped in a CONFIG_STACK_GROWSUP/DOWN test...)

-Kees
Kees Cook March 28, 2017, 10:34 p.m. UTC | #2
On Thu, Feb 16, 2017 at 4:54 PM, Kees Cook <keescook@chromium.org> wrote:
> On Thu, Feb 16, 2017 at 10:29 AM, James Morse <james.morse@arm.com> wrote:
>> Hi all,
>>
>> This version of Sahara's arch_within_stack_frames() series replaces the
>> open-coded stack walker with a call to arm64's existing walker.
>>
>> Patch 2 can be tested independently with this change[0].
>>
>> lkdtm's use of unallocated stack regions is a separate problem, patch 3
>> tries to address this.
>>
>> Sahara, it would be good to get your review of this!
>> I'm afraid I omitted your patch-3 as it stopped the lkdtm test from working,
>> I suspect its not tricking the compiler, but I haven't investigated.
>>
>>
>> Thanks,
>>
>> James
>>
>> [0] Change to lkdtm to generate accesses that overlap stack frames.
>> --------------%<--------------
>> diff --git a/drivers/misc/lkdtm_usercopy.c b/drivers/misc/lkdtm_usercopy.c
>> index 1dd611423d8b..fcbba3a14387 100644
>> --- a/drivers/misc/lkdtm_usercopy.c
>> +++ b/drivers/misc/lkdtm_usercopy.c
>> @@ -57,7 +57,8 @@ static noinline void do_usercopy_stack(bool to_user, bool bad_frame)
>>
>>         /* This is a pointer to outside our current stack frame. */
>>         if (bad_frame) {
>> -               bad_stack = do_usercopy_stack_callee((uintptr_t)&bad_stack);
>> +               bad_stack = __builtin_frame_address(0);
>> +               bad_stack -= sizeof(good_stack)/2;
>
> Ah, sneaky, yeah, that'll work nicely.
>
> (Though it should likely get wrapped in a CONFIG_STACK_GROWSUP/DOWN test...)

Is this still in progress? Seemed like it was very close?

-Kees
James Morse March 30, 2017, 8:30 a.m. UTC | #3
Hi Kees,

On 28/03/17 23:34, Kees Cook wrote:
> On Thu, Feb 16, 2017 at 4:54 PM, Kees Cook <keescook@chromium.org> wrote:
>> On Thu, Feb 16, 2017 at 10:29 AM, James Morse <james.morse@arm.com> wrote:
>>> This version of Sahara's arch_within_stack_frames() series replaces the
>>> open-coded stack walker with a call to arm64's existing walker.

> Is this still in progress? Seemed like it was very close?

Ah, sorry, I lost track of this when it jumped between mail folders... Sahara
had comments on the last patch.

How does all this fit with Al Viro's uaccess unification tree?:
https://lkml.org/lkml/2017/3/29/61


Thanks,

James
Kees Cook March 30, 2017, 7:54 p.m. UTC | #4
On Thu, Mar 30, 2017 at 1:30 AM, James Morse <james.morse@arm.com> wrote:
> Hi Kees,
>
> On 28/03/17 23:34, Kees Cook wrote:
>> On Thu, Feb 16, 2017 at 4:54 PM, Kees Cook <keescook@chromium.org> wrote:
>>> On Thu, Feb 16, 2017 at 10:29 AM, James Morse <james.morse@arm.com> wrote:
>>>> This version of Sahara's arch_within_stack_frames() series replaces the
>>>> open-coded stack walker with a call to arm64's existing walker.
>
>> Is this still in progress? Seemed like it was very close?
>
> Ah, sorry, I lost track of this when it jumped between mail folders... Sahara
> had comments on the last patch.
>
> How does all this fit with Al Viro's uaccess unification tree?:
> https://lkml.org/lkml/2017/3/29/61

It's orthogonal, though it results in bringing the hardened usercopy
to more architectures... (but the stack walker is still needed on a
per-arch basis).

-Kees
diff mbox

Patch

diff --git a/drivers/misc/lkdtm_usercopy.c b/drivers/misc/lkdtm_usercopy.c
index 1dd611423d8b..fcbba3a14387 100644
--- a/drivers/misc/lkdtm_usercopy.c
+++ b/drivers/misc/lkdtm_usercopy.c
@@ -57,7 +57,8 @@  static noinline void do_usercopy_stack(bool to_user, bool bad_frame)
 
        /* This is a pointer to outside our current stack frame. */
        if (bad_frame) {
-               bad_stack = do_usercopy_stack_callee((uintptr_t)&bad_stack);
+               bad_stack = __builtin_frame_address(0);
+               bad_stack -= sizeof(good_stack)/2;
        } else {
                /* Put start address just inside stack. */
                bad_stack = task_stack_page(current) + THREAD_SIZE;