Back

Fil-C: Garbage In, Memory Safety Out [video]

57 points1 dayyoutube.com
dang2 hours ago

There are getting to be quite a lot of these so I'll do it CPS style:

Memory Safe Context Switching - https://news.ycombinator.com/item?id=48727177 - June 2026 (30 comments)

Memory Safe Inline Assembly - https://news.ycombinator.com/item?id=48606096 - June 2026 (47 comments)

The Fil-C Optimized Calling Convention - https://news.ycombinator.com/item?id=48162876 - May 2026 (32 comments)

A simplified model of Fil-C - https://news.ycombinator.com/item?id=47810872 - April 2026 (136 comments)

Pizlix: Memory Safe Linux from Scratch - https://news.ycombinator.com/item?id=46260852 - Dec 2025 (30 comments)

Linux Sandboxes and Fil-C - https://news.ycombinator.com/item?id=46259064 - Dec 2025 (156 comments)

Ported freetype, fontconfig, harfbuzz, and graphite to Fil-C - https://news.ycombinator.com/item?id=46090009 - Nov 2025 (56 comments)

A Note on Fil-C - https://news.ycombinator.com/item?id=45842494 - Nov 2025 (210 comments)

Fil-C: A memory-safe C implementation - https://news.ycombinator.com/item?id=45842242 - Nov 2025 (1 comment)

Notes by djb on using Fil-C - https://news.ycombinator.com/item?id=45788040 - Nov 2025 (246 comments)

for more, goto https://news.ycombinator.com/item?id=45792588

wasmperson22 hours ago

He claims that all syscalls are safe because they're implemented by his custom libc, but that libc then calls out to the system libc, where the system calls are unsafe. He then claims that this is unlike rust, where making a syscall is unsafe. If you stick to the rust standard library in the same way that fil-c programs stick to the fil-c standard library, then all of your rust "system calls" are safe, too.

Someone in the audience also pointed out that a tool like this could be used to compile rust programs, not just C programs, in which case it's odd to hear Fil-C repeatedly framed as a language in opposition to rust rather than as a tool which might complement it.

modeless2 hours ago

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.

wasmperson50 minutes ago

> 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.

modeless46 minutes ago

Fil-C has access to a memory safe API called mmap with most of the capabilities of the mmap system call, while Rust's safe subset does not. Rust allows you to call 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.

minraws49 minutes ago

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.

quotemstr1 hour ago

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

jcranmer42 minutes ago

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

cypherpunk6662 hours ago

indeed, the ideas could be used more widely.

fil-c runs on linux.

what if linux ran on fil-c?

yjftsjthsd-h50 minutes ago

I was under the impression that fil-c's memory management (gc?) wouldn't work on a kernel? Be sweet if you could, ofc

doctorpangloss10 minutes ago

what if fil-c could draw pelicans?

LoganDark2 hours ago

> Someone in the audience also pointed out that a tool like this could be used to compile rust programs, not just C programs, in which case it's odd to hear Fil-C repeatedly framed as a language in opposition to rust rather than as a tool which might complement it.

You can combine both approaches for sure, but that doesn't change that they are indeed separate approaches. One (Rust) intends to characterize and prevent undefined behavior at compile time, and another (Fil-C) intends to make undefined behavior impossible at runtime, as evidenced by decisions like (for example) making unsafe usage of setjmp/longjmp safe.

You could sort of achieve "safety-in-depth" by combining both approaches, but Rust prefers to prevent all undefined behavior statically, and Fil-C prefers to focus on dynamic approaches. They have real differences, so that's probably what comes off as "oppositional"

raggi2 hours ago

This presentation wasn’t too bad in terms of us vs theming, but in general throughout the lifetime of the project there’s been a strong us vs them rhetoric. I think it’s working as a marketing tactic to some extent but there are better, albeit harder ways to market the thing.

LoganDark2 hours ago

Rust generally invites us vs them everywhere because it's just so ambitious and attractive (to some). Fil-C probably receives questions all the time about why they don't just do X or Y that Rust does. Maybe they end up supporting their position against that type of pressure and it looks like they're opposing Rust when all they're doing is justifying themselves.

uecker2 hours ago

Arguably the most important memory safety property, i.e. bounds checking for dynamic arrays, is also not statically checked in Rust.

wasmperson43 minutes ago

This isn't entirely true. Rust's indexing operator performs a dynamic check but the language and stdlib have a number of ways to access array elements without indexing, which is effectively a form of static checking. For example, the following loop is statically guaranteed to not go OOB, and will not emit any unnecessary bounds checks:

  for i in some_arr {
    println!("{i}");
  }
I suspect most techniques you could think of to statically avoid bounds checks are possible in rust's type system.
woodruffw2 hours ago

How would Rust perform static checks on dynamic bounds? That seems like an impossible order, i.e. not a reasonable evaluation criteria for any (general-purpose) language.

(I'm separately skeptical that it's the most important memory safety property; I suspect that a review of Chrome and Firefox 0days would show that UAFs and type confusion are, at least to attackers, equally if not more important.)

+1
zem1 hour ago
+2
LoganDark1 hour ago
LoganDark2 hours ago

It's possible to do this (WUFFS does it) but it's so invasive that, well, you basically end up with WUFFS. You end up having to track every set of possible and impossible values at every location, etc. (during each program location too.) WUFFS certainly has its place and I've kind of been itching to try it out myself, but I think getting to the point where dynamic arrays can be statically bounds-checked would have highly disabled Rust.

n422 hours ago

The combination of static safety gracefully degrading to runtime safety where not provable is interesting to me

LoganDark2 hours ago

This is sort of already possible in Rust when you use safe primitives (e.g., RefCell), but it doesn't cover unsafe code invoking Undefined Behavior. Placing something like Fil-C around unsafe code could prove to be interesting, especially since current approaches rely on interpretation (Miri, Soteria Rust) rather than translation.

cypherpunk6662 hours ago

also: why not use fil-c to improve cython, and the ffi.

FuckButtons43 minutes ago

the only reason to use cython (in my experience) is to write quick numpy extensions without a tonne of extra baggage from having a complete compiled extension in C/C++/Rust. Often, you explicitly want to avoid the compiler offering you any kinds of additional checking because you want to get maximum throughput. Most of the functions I’ve written in cython explicitly opt out of bounds checking etc since the memory access is sequential and bounded by construction and very obvious when you mess things up by writing simple unit tests. Given that, it doesn’t seem useful to me to add any kind of memory safety as additional overhead. YMMV I mostly do scientific computing and signal processing.

quotemstr2 hours ago

Both Rust and Fil-C have unsafe blocks, but in Fil-C latter system, only Pizlo gets to write them. Why am I not filled with confidence?

LugosFergus2 hours ago

I was just thinking that we were overdue for a Fil-C post on HN.

quotemstr59 minutes ago

Every one of these posts is the same. There's this weird blindness to the problems and imperfections in Fil-C --- just shouting down. It reduces my confidence in Fil-C as a whole.

Rust, for all its faults, at least engages with its critics. I've long faulted Rust's use of Result over exceptions, for example, but the maintainers at least acknowledge that other options exist and each has trade-offs. Not Pizlo and his fans.

To be clear, I like Fil-C. It's a practical implementation of something that should have existed a long time ago. And Pizlo is, in fact, a great programmer. It just rubs me the wrong way that he can't be content with having done excellent work --- he has to claim things that his system doesn't provide (like memory safety under data races --- minor fault, but still) and claim that other systems are worse in ways they are not (e.g. with respect to Rust having unsafe blocks).

Is genuine excellence not enough? Why must he persist in claiming a false perfection?

dundarious5 minutes ago

> claim that other systems are worse in ways they are not (e.g. with respect to Rust having unsafe blocks)

If considering only "safety", then Fil-C is more safe than any Rust containing unsafe blocks, no? With the usual caveats about whether an abort() is safe.

jagadaga21 minutes ago

>I've long faulted Rust's use of Result over exceptions

Why?