10 ms·
Fil-C: Garbage In, Memory Safety Out [video]
- wasmperson 2mo agoHe 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.
- cypherpunk666 2mo agoindeed, the ideas could be used more widely. fil-c runs on linux. what if linux ran on fil-c?
- yjftsjthsd-h 2mo agoI was under the impression that fil-c's memory management (gc?) wouldn't work on a kernel? Be sweet if you could, ofc
- brabel 2mo agoThis is a myth that seems to never die. OS kernels can and have been written in GC languages. Watch the video maybe? The whole presentation was running on a distro fully compiled with FillC.
- yjftsjthsd-h 2mo agoThe video has a slide which says, > I'm running on an OS where the entire userland is compiled with Fil-C/C++ (emphasis mine) Looking up https://fil-c.org/pizlix https://fil-c.org/pizlix , that says, > The kernel is compiled with Yolo-C. So that you can compile the kernel, a copy of GCC is installed in /yolo/bin/gcc. Where do you see anything saying the Linux (the kernel) can be built with Fil-C?
- brabel 2mo agoOk, I stand corrected: only the kernel userland was compiled with Fil-C. However, I don't see why the full Linux kernel could not be compiled with Fil-C. It would be nice if Fil himself could explain what limitations there are, but the documentation does not list missing C/C++ features as far as I know, it only says it's "fanatically compatible" which I take to mean mostly everything should work?! But to my point in general, here's a osdev.org wiki explaining how high level languages can and have been used for OS development (with the caveat that some Assembly code is required, which I believe is also true of kernels written in C): https://wiki.osdev.org/Languages https://wiki.osdev.org/Languages
- doctorpangloss 2mo agowhat if fil-c could draw pelicans?
- josephg 2mo agoDo you want your kernel to be 2x slower and use 4x as much memory?
- wavemode 2mo agoA computer spends the vast majority of its time and memory in userspace, so this tradeoff isn't as bad as it sounds.
- josephg 2mo agoThe benefit also isn’t as big as you might expect. Most of Linux’s recently found security vulnerabilities were due to ToC/ToU bugs. Fil-C would not magically fix these problems. It would sometimes be a good trade off, for some users. But I don’t think many regular users would choose to pay this cost.
- cypherpunk666 2mo agoa fun exercise is to ask an LLM how it might be applied.
- avadodin 2mo agoYou can run your Fil–C userland on provably–secure seL4. (Left as an exercise for the reader)
- josephg 2mo agoIf you’re using SeL4, userland processes are already strictly sandboxed. There’s still some benefit to Fil-C, since the added memory safety would make it much more difficult to take over a process. But the blast radius of a compromised program in SeL4 is much smaller because of the capability model.
- LoganDark 2mo 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"
- uecker 2mo agoArguably the most important memory safety property, i.e. bounds checking for dynamic arrays, is also not statically checked in Rust.
- LoganDark 2mo agoIt'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.
- woodruffw 2mo agoHow 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.)
- cypherpunk666 2mo agoalso: why not use fil-c to improve cython, and the ffi.
- FuckButtons 2mo agothe 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.
- josephg 2mo agoIf you want a slow, garbage collected language in the Python ecosystem, why not just write Python?
- cypherpunk666 2mo agoyou would. python and ffi would have runtime sanity checks a la fil-c. better error messages too. ask your favorite LLM how it would look.
- quotemstr 2mo agoBoth 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?
- pizlonator 2mo agoFil-C has no unsafe blocks
- modeless 2mo agoRust 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.
- quotemstr 2mo agoOkay, let me know when I can call process_vm_writev or ptrace and have Fil-C verify safety properties on the result.
- jcranmer 2mo agoDon't forget reads and writes of /proc/self/mem! :-)
- modeless 2mo agoBetter 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.
- pizlonator 2mo agoSure 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
- pizlonator 2mo agoCustom libc does not call to system libc. “Custom” and “system” aren’t the terms I use; I say user libc and you libc (because they are basically the same libc - either both are musl or both are glibc). User libc calls to the Fil-C runtime, which filters syscalls, and those filtered syscalls are made via yolo libc. Hence, a Fil-C program is memory safe down to the syscalls and syscalls cannot be used to escape the protections (unless you do weird stuff with /proc)
- wasmperson 2mo agoThe way I see it, as far as memory safety is concerned that's just framing. Both Fil-C and Rust have a boundary below which the unsafe lives. If Fil-C is only safer than rust when you don't pass the `-F unsafe_code` argument to rustc then IMO "safer" in this case is somewhat of an empty claim.
- flumpcakes 2mo agoI think you should watch the linked presentation, it will show how it is "safer" than rust. Unfortunately there are performance implications, but fil-c seems fast enough to go into production for many workloads and surprisingly needs very little code changes to existing C/C++ projects which is a huge benefit.
- josephg 2mo agoI think Fil-C might make a lot of sense for running legacy C or C++ codebases. But for new code, it seems like it’s trying to compete with other GC languages. Take away C’s performance advantages and I don’t know why anyone would use it. Fil-C: Combining the ergonomics of C with the performance of Python!
- pizlonator 2mo agoFil-C is much faster than Python And it’s fun to write new code in.
- 2mo ago
- mort96 2mo agoIn Rust, there are safe syscall wrappers, and then there's the unsafe general `syscall` function: https://docs.rs/libc/latest/libc/fn.syscall.html https://docs.rs/libc/latest/libc/fn.syscall.html. If I'm understanding correctly, it's this general syscall function that's safe in Fil-C.
- LugosFergus 2mo agoI was just thinking that we were overdue for a Fil-C post on HN.
- quotemstr 2mo agoEvery 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?
- jagadaga 2mo ago>I've long faulted Rust's use of Result over exceptions Why?
- AlotOfReading 2mo agoNot the person you're asking, but result types pessimize code more, add register pressure, use more icache for largely dead code, etc. They're arguably noisier at the source level too. That said, I've spent too much of my life chasing implicit control flow to accept exceptions. Heck, C++'s "noexcept" is a strong argument against exceptions all by itself.
- anon-3988 2mo agoI don't understand why Result type is necessarily slower. Result that simply bubbles up is basically an exception, no?
- dang 2mo agoThere 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 https://news.ycombinator.com/item?id=48727177 - June 2026 (30 comments) Memory Safe Inline Assembly - https://news.ycombinator.com/item?id=48606096 https://news.ycombinator.com/item?id=48606096 - June 2026 (47 comments) The Fil-C Optimized Calling Convention - https://news.ycombinator.com/item?id=48162876 https://news.ycombinator.com/item?id=48162876 - May 2026 (32 comments) A simplified model of Fil-C - https://news.ycombinator.com/item?id=47810872 https://news.ycombinator.com/item?id=47810872 - April 2026 (136 comments) Pizlix: Memory Safe Linux from Scratch - https://news.ycombinator.com/item?id=46260852 https://news.ycombinator.com/item?id=46260852 - Dec 2025 (30 comments) Linux Sandboxes and Fil-C - https://news.ycombinator.com/item?id=46259064 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 https://news.ycombinator.com/item?id=46090009 - Nov 2025 (56 comments) A Note on Fil-C - https://news.ycombinator.com/item?id=45842494 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 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 https://news.ycombinator.com/item?id=45788040 - Nov 2025 (246 comments) for more, goto https://news.ycombinator.com/item?id=45792588 https://news.ycombinator.com/item?id=45792588
- tialaramex 2mo agoHa, looking through the links dang added, I came upon something I wrote back in December I gave (somewhat arbitrarily) the example that safe Rust is OK with a 64-bit pointer (on a modern PC for example) having the value made by the UTF-8 text "LAUGHING". That's 8 bytes, 8 bytes is 64 bits, it fits perfectly. Of course I point out, unsafe Rust, which is allowed to dereference pointers, must never dereference this LAUGHING pointer, it's not actually pointing at anything, but it is allowed to exist in safe Rust. Coincidentally, in like February or so this year, a new third-party Rust type "ColdString" was introduced to their reddit by somebody I've never met - I read about it and encouraged its author. ColdString is 64 bits (on modern hardware) because inside it's a pointer, and indeed if the text you wanted to store in a ColdString was "LAUGHING" you do that exactly as I described in the December post - it's just the UTF-8 encoded text, no problem. The clever trick inside ColdString is how it can know when that 64-bit pointer really is actually a pointer for longer strings - yet also allows any 0 to 8 byte UTF-8 text string to just be encoded in the ColdString itself directly.
- bonzini 2mo agoHow does it do that? When the 64-bit pointer is actually a pointer, does it mangle it into something that is certainly not UTF-8 (e.g. changing its top byte to 0xC0, and assuming that bits 56-63 are the same as bits 48-55, or something like that)?
- tialaramex 2mo agoUTF-8 is a self-synchronizing encoding, so each UTF-8 byte tells you whether there were any previous bytes you'd need in order to understand it. Since we're storing a whole string our first byte logically cannot be such a "continuation byte", if it seems to be, we can say these eight bytes aren't UTF-8 encoded text but instead a pointer. The UTF-8 "continuation" marker is that the top bit is set and the next bit is not. So, we need to smash two bits of our pointer. Now, by pointing only at memory aligned to 4 bytes, the way a 32-bit integer would be on a typical machine, the bottom two bits of the pointer are always zero. So, we ask for such 4-byte aligned pointers when allocating memory to point at, most allocators actually never give out smaller alignments anyway because they cause problems in C but we've told the allocator our requirement so even if it could it won't give out unaligned pointers. Finally we need to re-arrange our pointer so that those two zero bits are in the right place to put a UTF-8 continuation marker. In Rust this is legal safe code, the map_addr method on a pointer is allowed to twiddle with a pointer's address bits (on typical platforms, all of them) and so long as your transform is reversible (which this one is) it will work correctly when you twiddle the pointer back and dereference that pointer in unsafe Rust.
- tschambers 2mo agoQuestion for the author from someone with no expertise in the field: how does Fil-C different from https://security.apple.com/blog/memory-integrity-enforcement/ https://security.apple.com/blog/memory-integrity-enforcement...? I'm guessing the hardware of the latter is something that Fil-C doesn't necessarily rely on.
- ndesaulniers 2mo agoI like the inline asm sanitizer; probably could be extracted out of Fil-C.
- JoelJacobson 2mo agoI was amazed by the presentation all the way up until 33:47, where the buggy program compiles and only errors out when the invalid access is executed. So apparently Fil-C enforces memory safety dynamically at run-time, rather than detecting these bugs at compile-time. A new language designed around memory safety, such as Rust, can reject large and important classes of memory-safety bugs at compile-time. Rust does not catch everything at compile-time, like bounds checks and RefCell, which are checked at run-time(, and the problems due to unsafe and C interop like explained in the presentation.) Still, IMO the comparison becomes a bit apples vs pears when bragging about how much more memory-safe Fil-C is than Rust. It would have been helpful to explain this important difference about run-time vs compile-time. Very cool and useful anyway.
- reanimus 2mo agoThe author's whole schtick is purposefully rage-baiting Rust devs, so really not that shocking that he downplays the compile-time trade-off
- flumpcakes 2mo agoI thought it was very obvious throughout the video what was happening... Rust has compile time checks to enforce some safety. In comparison Fil-C is a lot more memory safe, it's more comparable to being a software implementation of CHERI. Unfortunately it comes with downsides: runtime performance, runtime enforcement, granular safety (the safety is around allocations). It also comes with huge upsides: you can run C/C++ with little to no code changes. Imagine compiling nginx and the associated system libraries with Fil-C, the performance hit is probably acceptable and now the web server is memory safe. Rust probably provides enough memory safety (even if it is not complete safety) in most circumstances though.
- JoelJacobson 2mo agoI'm not a native English speaker, I know "memory safe" has a precise technical meaning, but the word "safe" still feels a bit strange to me given that a memory-safety bug can make the program crash at run-time. Sure, Fil-C prevents the bug from possibly being exploited, which is a huge improvement. But crashing can be a DoS attack, and if running a mission-critical system, it might not be an acceptable outcome. I just feel the already very good presentation could have been made much better if it had put more weight on explaining these trade-offs.
- Panzerschrek 2mo agoYet another prove of the idea that worse is better. First people use unsafe poorly-designed languages for writing critical software (already worse). Then someone invents a hack making code 4x slower and consuming 2x more memory to "fix" safety issues (much worse).
- Panzerschrek 2mo agoWho is the author of this project? Is it a single person? A small team? A single person with LLMs?
- zdimension 2mo agoFilip Pizło (https://www.filpizlo.com/ https://www.filpizlo.com/), according to his website: Director of Programmability and Data Model at Roblox. Previously, I worked at Epic Games (Senior Director of Language Engineering) and Apple (Manager of the JavaScriptCore Team). He seems to be the main developer of Fil-C: https://github.com/pizlonator/fil-c https://github.com/pizlonator/fil-c although there are other contributors.
- ivanjermakov 2mo agoFilip mentioned in the talk that Fil-C is his personal project.
- Panzerschrek 2mo agoI am asking, because I doubt a single person can achieve this. It requires at least a team of several people.