2 ms·
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 vo
by modeless 3mo ago
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.
- pizlonator 3mo 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
- modeless 3mo agoFully 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.
- josephg 3mo agoHow does it compare to the equivalent code in Typescript, Go or C#? Those languages all have “safe” syscall wrappers too, for a subset of syscalls.
- pizlonator 3mo agoThose languages rely on a much larger pile of YOLO C/C++ code for their runtimes and standard libraries than Fil-C does. So Fil-C is safer than those
- josephg 3mo agoThe number of lines of raw C isn’t the only way to measure the trustworthiness of a codebase. Go, C# and friends may be bigger projects. But they’re also more mature projects. At this point, far more eyeballs have scoured their codebases looking for security bugs. > Fil-C is safer than those Says you. It seems presumptuous to me to be so dismissive of their work. The Go and C# teams do good work. But I wasn’t even asking about safety. I’m curious about ergonomics and performance. Fil-C isn’t the only safe wrapper around raw syscalls. How is cross OS compatibility with Fil-C? How nice are the APIs to use? UNIX syscalls are pretty badly designed imo. The error paths alone are a mess.
- ncruces 3mo agoGo doesn't rely on much C/C++, not recently at least. Particularly on Linux.
- Splizard 3mo agoSmall nitpick but Go doesn't really have any YOLO C/C++ code in its runtime and standard library.
- pizlonator 3mo agoYeah what I said is true of TS and C#, but not of Go. Go’s situation is nuanced since a lot of Go code does rely on unsafe C or C++ deps, but I have no idea how generally true that is. Also Go’s protections fall apart under certain races, which isn’t true in Fil-C.
- quotemstr 3mo agoRaces in Fil-C allow access to one object through a pointer to a different object if there's an attacker-controlled offset involved. Fil-C's safety guarantees therefore fail to apply in this situation.
- pizlonator 3mo agoNonsense. In a race, you at worst access an object you could have loaded from whatever field you were racing on. In Go, you can bypass all protections and corrupt all of memory if you race on structs (I think).
- quotemstr 3mo ago> In a race, you at worst access an object you could have loaded from whatever field you were racing on. Suppose a pointer ptr is initialized to foo and transitions once to bar; suppose also that x is attacker-controlled. Then, T1: T* p = ptr; if (p == bar) p[x] = 7 T2: ptr = bar A program can observe p == bar (testing the address bits) but still permit a write to foo through p (allowed by the stale capability bits after offset by attacker-controlled x), allowing T1 to perform an unexpected mutation of foo. No, you do not always trap in this scenario, as you've claimed repeatedly on X. You perform the capability check after combining p and x. If an attacker sets x == foo - bar, then p[x] refers to memory inside foo even if p == bar. Because (for understandable reasons) you don't insert a memory barrier between a write of a pointer's address bits and its capabilities, use two-word atomic accesses, STM, or in any other way synchronize writes to pointer addresses and capabilities, programs with data races can observe arbitrary combinations of linear addresses and capabilities that go along with them. Plenty of exploit chains have had humbler beginnings. This access-foo-through-pointer-to-bar scenario can't happen in Java. It can't happen in CHERI. It can happen in Fil-C. Yes, T1 at one time had a capability on foo, but the programmer intent is clearly to mutate only bar, and Fil-C allows an execution that mutates foo instead. Elsewhere, you've claimed such executions cannot be exploited. I am skeptical of this claim given previous exploits that began by the camel poking its nose through similarly innocuous-seeming holes in the tent. Fil-C cannot fully protect C programs from exploitable memory corruption caused by violations of the C virtual machine. 99.9% of practical ones? Sure! Fil-C is good stuff. But there are holes (not only here, but for arenas, intra-object corruption, etc.), and these are holes that safe Rust prevents. Fil-C and Rust rules prohibit different (but mostly overlapping) classes of exploit. Could you define Fil-C's behavior as "memory safety"? Sure. You can define words to mean anything. You cannot, however, define Fil-C as something that just deletes the security implications of bugs in existing C programs. Does it mostly achieve this goal? Sure. Does it supply comprehensive coverage? No! It's a hardening tool, not a panacea, and it would behoove you to represent it as the useful tool it is, not magic pixie dust that makes C safe. Please stop ruining a tool as good as Fil-C by claiming it does things it does not and cannot. > In Go, you can bypass all protections and corrupt all of memory if you race on structs (I think). This is my understanding as well. I'm glad we agree, opinions on Fil-C memory model counting as "safe" aside, that Go is awful.
- quotemstr 3mo agoIf we strip away the semantic maneuvering, your argument becomes this: Rust is unsafe because it lets people who aren't you, Pizlo, write unsafe code. Safety means trusting only you with machine code. Anyone could do the same with a Rust lint rule if he wanted. He wouldn't, because this policy is not the way to secure software.