Re: [kernel-hardening] Re: [RFC v2][PATCH 04/11] x86: Implement __arch_rare_write_begin/unmap()
From: Andy Lutomirski
Date: Sat Apr 08 2017 - 01:11:37 EST
On Fri, Apr 7, 2017 at 9:21 PM, Daniel Micay <danielmicay@xxxxxxxxx> wrote:
>>> Fair enough. However, placing a BUG_ON(!(read_cr0() & X86_CR0_WP))
>>> somewhere sensible should make those "leaks" visible fast -- and their
>>> exploitation impossible, i.e. fail hard.
>>
>> The leaks surely exist and now we'll just add an exploitable BUG.
>
> That didn't seem to matter for landing a rewrite of KSTACKOVERFLOW
> with a bunch of *known* DoS bugs dealt with in grsecurity and those
> were known issues that were unfixed for no apparent reason other than
> keeping egos intact. It looks like there are still some left...
>
> In that case, there also wasn't a security/performance advantage.
This is wildly off topic, but I think it's worth answering anyway
because there's an important point here:
grsecurity and PaX are great projects. They have a lot of good ideas,
and they're put together quite nicely. The upstream kernel should
*not* do things differently from they way they are in grsecurity/PaX
just because it wants to be different. Conversely, the upstream
kernel should not do things the same way as PaX just to be more like
PaX.
Keep in mind that the upstream kernel and grsecurity/PaX operate under
different constraints. The upstream kernel tries to keep itself clean
and to make tree-wide updates rather that keeping compatibility stuff
around. PaX and grsecurity presumably want to retain some degree of
simplicity when porting to newer upstream versions.
In the context of virtually mapped stacks / KSTACKOVERFLOW, this
naturally leads to different solutions. The upstream kernel had a
bunch of buggy drivers that played badly with virtually mapped stacks.
grsecurity sensibly went for the approach where the buggy drivers kept
working. The upstream kernel went for the approach of fixing the
drivers rather than keeping a compatibility workaround. Different
constraints, different solutions.
The point being that, if someone sends a patch to the x86 entry code
that's justified by "be like PaX" or by "be different than PaX",
that's not okay. It needs a real justification that stands on its
own.
In the case of rare writes or pax_open_kernel [1] or whatever we want
to call it, CR3 would work without arch-specific code, and CR0 would
not. That's an argument for CR3 that would need to be countered by
something. (Sure, avoiding leaks either way might need arch changes.
OTOH, a *randomized* CR3-based approach might not have as much of a
leak issue to begin with.)
[1] Contrary to popular belief, I don't sit around reading grsecurity
code or config options, so I really don't know what this thing is
called.