* Robert O'Callahan <robert@xxxxxxxxxxxxx> wrote: > On Sat, Apr 27, 2019 at 10:46 PM Ingo Molnar <mingo@xxxxxxxxxx> wrote: > > - 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