Kernel Panic

Jason A. Donenfeld Jason at zx2c4.com
Tue Dec 6 23:39:36 CET 2016


Hey PaXTeam,

I tracked down Samuel's bug to this line in crypto/scatterwalk.c:
        if (sg_page(sg) == virt_to_page(realbuf) &&

virt_to_page is redefined for CONFIG_GRKERNSEC_KSTACKOVERFLOW:

#define virt_to_page(kaddr)     \
       ({ \
               const void *__kaddr = (const void *)(kaddr); \
               BUG_ON(!virt_addr_valid(__kaddr)); \
               pfn_to_page(__pa(__kaddr) >> PAGE_SHIFT); \
       })

So that's where the bug is hit. Now why is this happening?

I call scatterwalk_map_and_copy to read or write from or to a stack
buffer from a scattergather list, inside some crypto code that does
MAC checking. When virt_addr_valid(__kaddr) returns false, it is only
after PaX has additionally messed with its value. A few lines above
the call to virt_to_page is:

#ifdef CONFIG_GRKERNSEC_KSTACKOVERFLOW
       if (object_starts_on_stack(buf))
               realbuf = buf - current->stack + current->lowmem_stack;
#endif

Presumably this condition winds up being true, and then that
arithmetic is wrong somehow. Alternatively, that condition isn't true
due to a bug in object_starts_on_stack, and that arithmetic doesn't
run when it needs to run.

Samuel reported that the problem did not exist on 4.7 but does exist
on 4.8. If my memory serves me correctly, 4.8 introduced virtually
mapped stacks. Could it be that this virtual mapping now eliminates
the need for that arithmetic?

Regards,
Jason


More information about the WireGuard mailing list