Re: [RFC PATCH 2/7] x86/sci: add core implementation for system call isolation

From: Andy Lutomirski
Date: Fri Apr 26 2019 - 17:26:43 EST


> On Apr 26, 2019, at 2:58 AM, Ingo Molnar <mingo@xxxxxxxxxx> wrote:
>
>
> * Ingo Molnar <mingo@xxxxxxxxxx> wrote:
>
>> I really don't like it where this is going. In a couple of years I
>> really want to be able to think of PTI as a bad dream that is mostly
>> over fortunately.
>>
>> I have the feeling that compiler level protection that avoids
>> corrupting the stack in the first place is going to be lower overhead,
>> and would work in a much broader range of environments. Do we have
>> analysis of what the compiler would have to do to prevent most ROP
>> attacks, and what the runtime cost of that is?
>>
>> I mean, C# and Java programs aren't able to corrupt the stack as long
>> as the language runtime is corect. Has to be possible, right?
>
> So if such security feature is offered then I'm afraid distros would be
> strongly inclined to enable it - saying 'yes' to a kernel feature that
> can keep your product off CVE advisories is a strong force.
>
> To phrase the argument in a bit more controversial form:
>
> If the price of Linux using an insecure C runtime is to slow down
> system calls with immense PTI-alike runtime costs, then wouldn't it be
> the right technical decision to write the kernel in a language runtime
> that doesn't allow stack overflows and such?
>
> I.e. if having Linux in C ends up being slower than having it in Java,
> then what's the performance argument in favor of using C to begin with?
> ;-)
>
> And no, I'm not arguing for Java or C#, but I am arguing for a saner
> version of C.
>
>

IMO three are three credible choices:

1. C with fairly strong CFI protection. Grsecurity has his (supposedly
â thereâs a distinct lack of source code available), and clang is
gradually working on it.

2. A safe language for parts of the kernel, e.g. drivers and maybe
eventually filesystems. Rust is probably the only credible candidate.
Actually creating a decent Rust wrapper around the core kernel
facilities would be quite a bit of work. Things like sysfs would be
interesting in Rust, since AFAIK few or even no drivers actually get
the locking fully correct. This means that naive users of the API
cannot port directly to safe Rust, because all the races won't compile
:)

3. A sandbox for parts of the kernel, e.g. drivers. The obvious
candidates are eBPF and WASM.

#2 will give very good performance. #3 gives potentially stronger
protection against a sandboxed component corrupting the kernel
overall, but it gives much weaker protection against a sandboxed
component corrupting itself.

In an ideal world, we could do #2 *and* #3. Drivers could, for
example, be written in a language like Rust, compiled to WASM, and run
in the kernel.