Thread (41 messages) 41 messages, 10 authors, 2019-05-02

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

From: Ingo Molnar <mingo@kernel.org>
Date: 2019-05-02 15:20:24
Also in: linux-mm, lkml

* Robert O'Callahan [off-list ref] wrote:
On Sat, Apr 27, 2019 at 10:46 PM Ingo Molnar [off-list ref] wrote:
quoted
 - A C language runtime that is a subset of current C syntax and
   semantics used in the kernel, and which doesn't allow access outside
   of existing objects and thus creates a strictly enforced separation
   between memory used for data, and memory used for code and control
   flow.

 - This would involve, at minimum:

    - tracking every type and object and its inherent length and valid
      access patterns, and never losing track of its type.

    - being a lot more organized about initialization, i.e. no
      uninitialized variables/fields.

    - being a lot more strict about type conversions and pointers in
      general.

    - ... and a metric ton of other details.
Several research groups have tried to do this, and it is very
difficult to do. In particular this was almost exactly the goal of
C-Cured [1]. Much more recently, there's Microsoft's CheckedC [2] [3],
which is less ambitious. Check the references of the latter for lots
of relevant work. If anyone really pursues this they should talk
directly to researchers who've worked on this, e.g. George Necula; you
need to know what *didn't* work well, which is hard to glean from
papers. (Academic publishing is broken that way.)

One problem with adopting "safe C" or Rust in the kernel is that most
of your security mitigations (e.g. KASLR, CFI, other randomizations)
probably need to remain in place as long as there is a significant
amount of C in the kernel, which means the benefits from eliminating
them will be realized very far in the future, if ever, which makes the
whole exercise harder to justify.

Having said that, I think there's a good case to be made for writing
kernel code in Rust, e.g. sketchy drivers. The classes of bugs
prevented in Rust are significantly broader than your usual safe-C
dialect (e.g. data races).

[1] https://web.eecs.umich.edu/~weimerw/p/p477-necula.pdf
[2] https://www.microsoft.com/en-us/research/uploads/prod/2019/05/checkedc-post2019.pdf
[3] https://github.com/Microsoft/checkedc
So what might work better is if we defined a Rust dialect that used C 
syntax. I.e. the end result would be something like the 'c2rust' or 
'citrus' projects, where code like this would be directly translatable to 
Rust:

void gz_compress(FILE * in, gzFile out)
{
	char buf[BUFLEN];
	int len;
	int err;

	for (;;) {
		len = fread(buf, 1, sizeof(buf), in);
		if (ferror(in)) {
			perror("fread");
			exit(1);
		}
		if (len == 0)
			break;
		if (gzwrite(out, buf, (unsigned)len) != len)
			error(gzerror(out, &err));
	}
	fclose(in);

	if (gzclose(out) != Z_OK)
		error("failed gzclose");
}


#[no_mangle]
pub unsafe extern "C" fn gz_compress(mut in_: *mut FILE, mut out: gzFile) {
    let mut buf: [i8; 16384];
    let mut len;
    let mut err;
    loop  {
        len = fread(buf, 1, std::mem::size_of_val(&buf), in_);
        if ferror(in_) != 0 { perror("fread"); exit(1); }
        if len == 0 { break ; }
        if gzwrite(out, buf, len as c_uint) != len {
            error(gzerror(out, &mut err));
        };
    }
    fclose(in_);
    if gzclose(out) != Z_OK { error("failed gzclose"); };
}

Example taken from:

   https://gitlab.com/citrus-rs/citrus

Does this make sense?

Thanks,

	Ingo
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help