struct User {
char name[100];
bool is_admin;
};
Where a buffer overflow can still overwrite `is_admin`.Both also require recompilation of everything, which might be possible for CHERI but not for Fil-C - which is why, for example, there cannot be Fil-C support for Windows or macOS.
You can also limit access permissions IIUC; I'm only going by old memory here, but you'd be able to hand out a read-only pointer derived from an RWX pointer.
This "name overflows to is_admin" example doesn't come up in real code or real CVEs. It does come up in HN comments on Fil-C threads though.
CHERI is less compatible than Fil-C, in terms of how many changes you have to make to code to make it work, and this is an example of a policy decision that causes that result.
It is interesting that C++ decided to disallow it in compile time evaluation ( constexpr contexts ).
I have already seen fixes where code that used pointer arithmetic to go from one struct member to another generated garbage in real-world gamedev projects. That code had been like that for 20+ years and worked fine, then suddenly broke after toolchain update.
What makes memory safety so important is that in C/C++, a missing bounds check on `name` gives you access to the entire heap, not simply the other fields within that allocation. Attackers aren't using missing bounds checks to look for `is_admin` fields in the same object. They're looking for a pivot to full memory control, so they can plug in their RCE exploit chain. So, the only time that attackers are looking for an intra-object overflow is if they have something like `struct { char buf[100]; void* ptr; }`, since that does lead to a pivot to full memory control. Fil-C protects that; you can't use that overflow to corrupt `ptr`'s capability.
This is why memory safety tech like MIE, MTE, and Fil-C focus on allocation granularity. If I wanted to support subobject granularity, I could; it's not a huge change to the capability model. Fil-C's first two capability models (back in late 2023, early 2024) supported subobject granularity. I'm choosing not to support it now because I understand the security implications well enough to know that it's not worth the complexity.
Fil-C started out as a macOS project. Fil-C supports Windows and macOS today via APE. Requiring recompiliation of everything is a luxury I can choose to support on Linux that results in memory safety of the whole process. If you find Fil-C useful and understand compilers, you could probably get a variant working that has FFI and then expose Windows and Mac API to it. You'd get something with a weaker safety guarantee, but no weaker than what you get today from Rust or Java.
There are many orders of magnitude fewer real exploits using intra-struct overflow without pointer control than there are exploits using vanilla logic bugs (like the programmer forgot to check the is_admin bit before proceeding to the admin privileges business logic).
So, obsessing over intra-struct overflows in a language that prevents ptr-int type confusion is missing the plot.
(Believe me, if intra-struct overflows over primitives were a big threat, I'd change the Fil-C policy.)