Rust doesn't runtime validate that your usage of syscalls is memory safe, while Fil-C does. For example you can call mmap in Fil-C and it is still guaranteed to be memory safe, while in Rust you can easily violate memory safety by calling mmap. This seems like an unambiguous improvement to me. This is as memory safe as it is possible to be on a system with a kernel that is not memory safe.

Adding Fil-C-like runtime checks to Rust is definitely an interesting direction.

> For example you can call mmap in Fil-C and it is still guaranteed to be memory safe, while in Rust you can easily violate memory safety by calling mmap.

That's the thing, though. Your Fil-C code isn't calling mmap, it's calling the Fil-C wrapper for mmap. In neither Fil-C nor Rust('s safe subset) can you call the actual system mmap.

Fil-C has access to a memory safe API called mmap with a lot of the capabilities of the mmap system call, while Rust's safe subset does not. Rust allows you to use the mmap system call unsafely, while Fil-C does not. I feel these are both big advantages for Fil-C. You'll never have to audit a Fil-C codebase to determine whether its calls to mmap are memory safe, or indeed any other calls to any API or dependency, even those written in C.

How is Fil-C’s wrapper approach different from someone (not necessarily the Rust stdlib) implementing a safe wrapper around a particular syscall?

mmap is a bit of an outlier because it is not possible to implement a fully featured safe wrapper (MAP_SHARED) in Rust. So I would be curious to see what safety guarantees Fil-C claims to provide for mmap.

> from someone (not necessarily the Rust stdlib) implementing a safe wrapper around a particular syscall?

You might call that library "nix"[1]. Many, though not all, of the bindings are safe wrappers around the underlying unsafe syscall.

(The specific call of mmap from upthread, though, that one is not. I'm not sure how you would make such a call safe.)

[1]: https://docs.rs/nix/latest/nix/index.html

Adding Fil-C-like runtime checks to Rust is definitely an interesting direction. As I mentioned upthread. It's not just the availability of the safe API that's interesting, though, but also the prohibition on using the unsafe API in the entire program and all dependencies. Which Rust could also do in theory but not yet in practice AFAIK.

Complete memory safety (much less concurrent garbage collection) isn’t really workable for things like kernel and some embedded programming contexts. Rust can work in those contexts precisely because it has an unsafe out.

Even so Fil-C fails at being 100% compatible for userspace due to the silly things people do with pointers. Hence the large amount of effort he’s had to do to fix up that 0.1% of userspace that breaks.

Rust is less safe because it has a feature for turning off safety, called `unsafe`. Fil-C does not have a way to turn off safety, and it enforces safety checks at runtime. That's the reasoning anyways. If you define another language Rust-Without-Any-Unsafe, then maybe that one is safer than Fil-C.

> If you define another language Rust-Without-Any-Unsafe, then maybe that one is safer than Fil-C.

Just write `#![forbid(unsafe_code)]` at the top of your src/lib.rs, and track crates not using it with `cargo geiger`. You don't need a whole new language, it already provides the tools to wield that hatch shut.

> Rust is less safe because it has a feature for turning off safety

Can I write Fil-C's mmap wrapper in Fil-C?

If no, fair enough, but it's worth noting I can write a safe Rust mmap wrapper in Rust, and I absolutely and frequently need to do that kind of "syscall wrapping" in arenas Fil-C explicitly hasn't handled, by virtue of being explicitly a Linux project.

If yes, that sounds like an escape hatch to Fil-C's memory safety, undermining the claim that Fil-C is fundamentally safer, and you're now at best arguing it's safer as tends to be used.

But the runtime cost of Fil-C means that - in most cases - your actual production application will be compiled with a standard C compiler. This applies not just to your code, but to all dependencies (due to ABI).

So I don’t see how Rust is at a huge disadvantage here when Fil-C is typically not going to be enforcing safety in production. I suppose the testing/fuzzing story becomes all the more important because you need to exercise runtime behavior for Fil-C to detect unsafe faults.

Don’t get me wrong: I think Fil-C is a smart idea and an excellent way to introduce memory safety to existing C codebases. But I don’t get this whole (usually implied) idea that Fil-C somehow makes Rust look bad or renders it obsolete.

The whole point of Fil-C is that it is fast enough to consider using in production for some applications while still guaranteeing memory safety. We already have ASAN and Valgrind and other tools for development purposes, that's not what Fil-C is targeting.

I am assuming that Fil-C introduces orders of magnitude less overhead than ASAN or Valgrind.

Also, it’s probably fast enough for apps to be deployed in something like a staging environment for integration tests to run against them. Production deploy/release can then happen using a tagged version that gets compiled using vanilla GCC/Clang.

ASAN is actually probably faster but doesn't guarantee memory safety. It's only for catching mistakes and not secure against an adversary. Valgrind is dramatically slower.

It doesn't work for a significant set of syscalls and is very very unlikely to ever work because of how the syscalls themselves work unless ofc you are willing to emulate them somehow which is a insane amount of additional compute cost.

Okay, let me know when I can call process_vm_writev or ptrace and have Fil-C verify safety properties on the result.

Don't forget reads and writes of /proc/self/mem! :-)

Better include Rowhammer too. Maybe Fil-C should run a test and refuse to start on any system with bad RAM or unpatched CPU errata. It could also monitor the voltage to protect against undervolting attacks. And you'll need some cosmic ray shielding too.

Of course I'm kidding, but it is absolutely the case that if you truly care about safety you need to consider more than the program source code and binary, but also the environment, including kernel and hardware. The user doesn't care if their web browser got hacked via stack buffer underflow or /dev/exynos-mem or Rowhammer; the result is the same.

Sure all of those are escape hatches that work against any memory safety tech.

Point is, Fil-C goes further than any other memory safety tech in terms of what it guards

Fully agreed. At some point you have to draw a line and say that the rest is the responsibility of the kernel and hardware and user, and I think Fil-C drew that line in the right place.