Re: KASAN vs vmapped stacks

From: Dmitry Vyukov
Date: Wed Jul 13 2016 - 05:55:53 EST


On Mon, Jul 11, 2016 at 4:10 PM, Andrey Ryabinin
<aryabinin@xxxxxxxxxxxxx> wrote:
>
>
> On 07/11/2016 01:29 PM, Dmitry Vyukov wrote:
>> On Mon, Jul 11, 2016 at 11:57 AM, Andrey Ryabinin
>> <aryabinin@xxxxxxxxxxxxx> wrote:
>>>
>>>
>>> On 07/10/2016 03:47 PM, Andy Lutomirski wrote:
>>>> Hi all-
>>>>
>>>> I found two nasty issues with virtually mapped stacks if KASAN is
>>>> enabled. The first issue is a crash: the first non-init stack is
>>>> allocated and accessed before KASAN initializes its zero shadow
>>>> AFAICT, which means that we switch to that stack and then blow up when
>>>> we start recursively faulting on failed accesses to the shadow.
>>>>
>>>
>>> KASAN initialized quite early, before any non-init task exists. The crash happens
>>> because non-init task writes to write-protected zero shadow.
>>> Currently KASAN doesn't allocate shadow memory for vmalloc addresses, we just map single
>>> zero page and write protect it.
>>>
>>>
>>>> The second issue is that, even if we survive (we initialize the zero
>>>> shadow on time), KASAN will fail to protect hte stack.
>>>>
>>>> For now, I just disabled use of virtually mapped stacks if KASAN is
>>>> on. Do you have any easy ideas to fix it?
>>>>
>>>
>>> Allocate shadow memory which backs vmalloc/vmap allocations is the only way to fix this.
>>> I can do this, and post the patches soon enough.
>>
>> Do you want to allocate it eagerly? Won't it consume 1/8 of vmalloc
>> range worth of physical memory?
>>
>
> I have no idea what do you mean by eager allocation.


For physical memory we preallocate whole shadow range at startup. This
consumes 1/8 of physical memory. That's what I meant by eager
allocation. Lazy allocation would be to allocate shadow for memory
when it's first allocated/used.

> What we need is to allocate shadow per vmalloc()/vmap() call if such allocation requires non-zero shadow, like stacks or modules.
> Sometimes we certainly know that the whole shadow page will contain only zeros. In such cases we can use zero page to not waste memory.

Do you want to add a gfp_t flag that says "this range requires writable shadow"?
Note that shadow for vmalloc memory will consume from 2/8 to 9/8,
because we back both virtual and physical addresses and because shadow
can be allocated only with page granularity. That's probably fine if
it is used only for kernel stacks.