Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Many programmers also learned to the use tools available to write reasonably safe code in C.

And then someone compiled their code with a new compiler and got a security bug. This happens consistently. Every C programmer thinks their code is reasonably safe until someone finds a security bug in it. Many still think so afterwards.



There are couple of cases where compiler optimizations caused security issues, but that this happens all the time is a huge exaggeration. And many of the practically relevant cases can be avoided by using tools such as UBSan. The actual practical issue in C is people getting their pointer arithmetic wrong, which can also be avoided by having safe abstractions for buffer and string handling.

The other fallacy is that these issue then suddenly would disappear when using Rust, which is also not the case. Because the programmer cutting corners in C or prioritizing performance over safety will also use Rust "unsafe" carelessly.

Rust has a clear advantage for temporal memory safety. But it is also possible to have a clear strategy about what data structure owns what other object in C.


> And many of the practically relevant cases can be avoided by using tools such as UBSan.

"can be", but aren't.

> The other fallacy is that these issue then suddenly would disappear when using Rust, which is also not the case. Because the programmer cutting corners in C or prioritizing performance over safety will also use Rust "unsafe" carelessly.

The vast majority of these programmers aren't making a deliberate choice at all though. They pick C because they heard it's fast, they write it in the way that the language nudges them towards, or the way that they see done in libraries and examples, and they end up with unsafe code. Sure, someone can deliberately choose unsafe in Rust, but defaults matter.

> it is also possible to have a clear strategy about what data structure owns what other object in C.

Is it though? How can one distinguish a codebase that does from a codebase that doesn't? Other than the expensive static analysis tool mentioned elsewhere in the thread (at which point you're not really writing "C"), I've never seen a way that worked and was distinguishable from the ways that don't work.


> > And many of the practically relevant cases can be avoided by using tools such as UBSan.

> "can be", but aren't.

It is a possible option when one needs improved safety, and IMHO often the better option than using Rust.

> > The other fallacy is that these issue then suddenly would disappear when using Rust, which is also not the case. Because the programmer cutting corners in C or prioritizing performance over safety will also use Rust "unsafe" carelessly.

> The vast majority of these programmers aren't making a deliberate choice at all > though. They pick C because they heard it's fast, they write it in the way that the > language nudges them towards, or the way that they see done in libraries and examples, > and they end up with unsafe code. Sure, someone can deliberately choose unsafe in > Rust, but defaults matter.

The choice of handcoding some low-level string manipulation is similar to the choice of using unsafe rust. One can do it or not. There is certainly a better security culture in Rust at this time, but it is unclear to what extend this will be true in the long run. Also C security culture improves too and Rust culture will certainly deteriorate when usage spreads from highly motivated early adopters to the masses.

> > it is also possible to have a clear strategy about what data structure owns what other object in C.

> Is it though? How can one distinguish a codebase that does from a > codebase that doesn't?

This leads to the argument that it is trivial to see unsafe code in Rust because it is marked "unsafe" and just a small amount of code while in C you would need to look at everything. But this largely a theoretical argument: In practice you need to do some quality control for all code anyway, because memory safety is just a small piece of overall the puzzle. (and even for memory safety, you also need to look at the code surrounding code in RUst.) In practice, it is not hard to recognize the C code which is dangerous, it is the one where pointer arithmetic and string manipulation is not encapsulated in safe interfaces and it is the code where ownership of pointers is not clear.

>Other than the expensive static analysis tool mentioned elsewhere in the thread (at which point you're not really writing "C"), I've never seen a way that worked and was distinguishable from the ways that don't work.

I see some very high quality C code with barely any memory safety problems. Expensive static analysis can be used when no mistakes are acceptable, but then you should also formally verify the unsafe code in Rust.


> The choice of handcoding some low-level string manipulation is similar to the choice of using unsafe rust. One can do it or not.

But most of the time programmers don't make a conscious choice at all. So opt-out unsafety versus opt-in unsafety is a huge difference.

> In practice you need to do some quality control for all code anyway, because memory safety is just a small piece of overall the puzzle.

Memory safety is literally more than half of real-world security issues.

> In practice, it is not hard to recognize the C code which is dangerous

> I see some very high quality C code with barely any memory safety problems

I hear a lot of C people saying this sort of thing, but they never make it concrete - there's no list of which popular open-source libraries are dangerous and which are not, it's only after a vulnerability is discovered that we hear "oh, that project always had poor quality code". If I pick a random library to maybe use in my project (even big-name ones e.g. libpq or libtiff), no-one can ever actually answer whether that's high quality C code or low quality C code, or give me a simple algorithm that I can actually apply without having to read a load of code and make a subjective judgement. Whereas I don't have to read or judge anything or even properly know rust to do "how much of this rust code is unsafe".


> > The choice of handcoding some low-level string manipulation is similar to the choice of using unsafe rust. One can do it or not.

> But most of the time programmers don't make a conscious choice at all. So opt-out unsafety versus opt-in unsafety is a huge difference.

I don't think so. A programmer being careless will be careless with Rust "unsafe" too.

Don't get me wrong, I think marking code without guaranteed memory safety is a good idea. I just don't think it is a fundamental game changer.

> > In practice you need to do some quality control for all code anyway, because memory safety is just a small piece of overall the puzzle.

> Memory safety is literally more than half of real-world security issues.

https://www.horizon3.ai/attack-research/attack-blogs/analysi...

But I think even this is likely overstating it by looking at CVEs and not real world impact.

> > > In practice, it is not hard to recognize the C code which is dangerous

> > I see some very high quality C code with barely any memory safety problems

> I hear a lot of C people saying this sort of thing, but they never make it > concrete - there's no list of which popular open-source libraries are dangerous > and which are not, it's only after a vulnerability is discovered that we hear > "oh, that project always had poor quality code". If I pick a random library > to maybe use in my project (even big-name ones e.g. libpq or libtiff), no-one > can ever actually answer whether that's high quality C code or low quality C code > or give me a simple algorithm that I can actually apply without having to read > a load of code and make a subjective judgement. Whereas I don't have to read or > judge anything or even properly know rust to do "how much of this rust code is unsafe".

So you look at all the 300 unmaintained dependencies a typical Rust projects pulls in via cargo and look at all the "unsafe" blocks to screen it? Seriously, the issue is lack of open-source man power and this will hit Rust very hard once the ecosystem gets larger and this goes even more beyond the highly motivated first adopters. I would be more tempted to buy this argument if Rust would have no "unsafe" and I could pull in arbitrary code from anywhere and be safe. And this idea existed before with managed languages... Safe Java in the browser and so. Also sounded plausible but was similarly highly exaggerated as the Rust story.


> A programmer being careless will be careless with Rust "unsafe" too.

Programmers will be careless, sure, but you can't really use unsafe without going out of your way to. Like, no-one is going to write "unsafe { *arr.get_unchecked(index) }" instead of "arr[index]" when they're not thinking about it.

> So you look at all the 300 unmaintained dependencies a typical Rust projects pulls in via cargo and look at all the "unsafe" blocks to screen it?

No, of course not, I run "cargo geiger" and let the computer do it.

I think unmaintained dependencies are less likely, and easier to check, in the Rust world. Ultimately what defines the attack surface is the number of lines of code, not how they're packaged, and C's approach tends to lead to linking in giant do-everything frameworks (e.g. people will link to GLib or APR when they just wanted some string manipulation functions or a hash table, which means you then have to audit the whole framework to audit that program's dependencies. And while the framework might look well-maintained, that doesn't mean that the part your program is using is), reimplementing or copy-pasting common functions because they're not worth adding a dependency for (which is higher risk, and means that well-known bugs can keep reappearing, because there's no central place to fix it once and for all), or both. And C's limited dependency management means that people often resort to vendoring, so even if your dependency is being maintained, those bugfixes may not be making their way into your program.

> And this idea existed before with managed languages... Safe Java in the browser and so. Also sounded plausible but was similarly highly exaggerated as the Rust story.

Java has quietly worked. It didn't succeed in the browser or on the open-source or consumer-facing desktop for reasons that had nothing to do with safety (in some cases they had to do with the perception of safety), but backend processing or corporate internal apps are a lot safer than they used to be, without really having to change much.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: