Re: [PATCH v2 01/11] mm: Implement stack frame object validation

From: Kees Cook
Date: Thu Jul 14 2016 - 14:10:29 EST


On Wed, Jul 13, 2016 at 10:48 PM, Josh Poimboeuf <jpoimboe@xxxxxxxxxx> wrote:
> On Wed, Jul 13, 2016 at 03:04:26PM -0700, Kees Cook wrote:
>> On Wed, Jul 13, 2016 at 3:01 PM, Andy Lutomirski <luto@xxxxxxxxxxxxxx> wrote:
>> > On Wed, Jul 13, 2016 at 2:55 PM, Kees Cook <keescook@xxxxxxxxxxxx> wrote:
>> >> This creates per-architecture function arch_within_stack_frames() that
>> >> should validate if a given object is contained by a kernel stack frame.
>> >> Initial implementation is on x86.
>> >>
>> >> This is based on code from PaX.
>> >>
>> >
>> > This, along with Josh's livepatch work, are two examples of unwinders
>> > that matter for correctness instead of just debugging. ISTM this
>> > should just use Josh's code directly once it's been written.
>>
>> Do you have URL for Josh's code? I'd love to see what happening there.
>
> The code is actually going to be 100% different next time around, but
> FWIW, here's the last attempt:
>
> https://lkml.kernel.org/r/4d34d452bf8f85c7d6d5f93db1d3eeb4cba335c7.1461875890.git.jpoimboe@xxxxxxxxxx
>
> In the meantime I've realized the need to rewrite the x86 core stack
> walking code to something much more manageable so we don't need all
> these unwinders everywhere. I'll probably post the patches in the next
> week or so. I'll add you to the CC list.

Awesome!

> With the new interface I think you'll be able to do something like:
>
> struct unwind_state;
>
> unwind_start(&state, current, NULL, NULL);
> unwind_next_frame(&state);
> oldframe = unwind_get_stack_pointer(&state);
>
> unwind_next_frame(&state);
> frame = unwind_get_stack_pointer(&state);
>
> do {
> if (obj + len <= frame)
> return blah;
> oldframe = frame;
> frame = unwind_get_stack_pointer(&state);
>
> } while (unwind_next_frame(&state);
>
> And then at the end there'll be some (still TBD) way to query whether it
> reached the last syscall pt_regs frame, or if it instead encountered a
> bogus frame pointer along the way and had to bail early.

Sounds good to me. Will there be any frame size information available?
Right now, the unwinder from PaX just drops 2 pointers (saved frame,
saved ip) from the delta of frame address to find the size of the
actual stack area used by the function. If I could shave things like
padding and possible stack canaries off the size too, that would be
great.

Since I'm aiming the hardened usercopy series for 4.8, I figure I'll
just leave this unwinder in for now, and once yours lands, I can rip
it out again.

-Kees

--
Kees Cook
Chrome OS & Brillo Security