6 ms·
"All it took was some basic understanding of memory management and a bit of discipline." The words of every C programmer who created a CVE.
by KingOfCoders 1y ago
"All it took was some basic understanding of memory management and a bit of discipline."
The words of every C programmer who created a CVE.
- markphip 1y agoCame here to add the same comment. Had it on my clipboard already to post. You said it better
- dev_l1x_be 1y agoThe amount of seggfaults I have seen with Ghostty did not raise my spirits.
- txdv 1y agoI haven't seen a single one.
- mlvljr 1y ago[dead]
- neerajk 1y agosegfaults raise my belief in spirits
- greesil 1y agoPossibly a good Halloween costume idea to go as a segfault. It would scare some people.
- dpatterbee 1y agoI've had at least one instance of Ghostty running on both my work and personal machine continuously since I first got access to the beta last November, and I haven't seen a single segfault in that entire time. When have you seen them?
- mr90210 1y agoGoogle: "wikipedia Evidence of absence" Also, https://github.com/ghostty-org/ghostty/issues?q=segfault https://github.com/ghostty-org/ghostty/issues?q=segfault
- dpatterbee 1y agoSo Ghostty was first publicly released on I think December 27th last year, then 1.0.1, 1.1.0, 1.1.1, and 1.1.2 were released within the next month and a half to fix bugs found by the large influx of users, and there hasn't been a segfault reported since. I would recommend that users who are finding a large number of segfaults should probably report it to the maintainers.
- metaltyphoon 1y agoLook at the issue tracker and its history too.
- dmit 1y agoI've seen the amount of effort Mitchell &co put into ensuring memory safety of Ghostty in the 1.2 release notes, but after upgrading I am still afraid to open a new pane while there's streaming output in the current one because in 1.1.3 that meant a crash more often than not.
- hnaccount19293 1y agoBun is much worse in this regard too.
- johncolanduoni 1y agoIt makes me sad, because they demonstrated JavaScriptCore is shockingly better than V8 for node-likes. The Typescript compiler (which like basically any non-trivial typechecker is CPU bound) is consistently at least 2x faster with Bun on large projects I've worked on.
- pjmlp 1y agoWhen Typescript finishes their Go rewrite that will become irrelevant, and I rather have the compiler from the same people that design the language.
- johncolanduoni 1y agoFor that example sure, and admittedly the entire JavaScript/TypeScript processing ecosystem is moving in that direction. But the TypeScript compiler is not the only CPU-bound JavaScript out there.
- pjmlp 1y agoThere are plenty of memory safe compiled languages to rewrite that JavaScript into.
- dayvster 1y agoSegfaults go brrr. All jokes aside, it doesn’t actually take much discipline to write a small utility that stays memory safe. If you keep allocations simple, check your returns, and clean up properly, you can avoid most pitfalls. The real challenge shows up when the code grows, when inputs are hostile, or when the software has to run for years under every possible edge case. That’s where “just be careful” stops working, and why tools, fuzzing, and safer languages exist.
- KingOfCoders 1y agoMy assumption is a small utility becomes a big utility.
- uecker 1y agoAnd a segfault would be worse than a panic, data corruption or out of memory access are the problems. But in reality, most C programs I use daily have never crashed in decades.
- zwnow 1y ago"Actually memory management is easy, you just have to...." - Every C programmer I've talked to No its not, if it was that easy C wouldn't have this many memory related issues...
- r_lee 1y agoIt may be easy to do memory management, but it's not too easy to detect if you've made a fatal mistake when such mistakes won't cause apparent defects avoiding all memory management mistakes is not easy, and the bigger the codebase becomes, the more exponential the chance for disaster gets
- zwnow 1y agoAbsolutely, big factor is undefined behavior which makes it look like everything works. Until it doesn't. I quit C long ago because I don't want to deal with manual memory management in any language. I was overwhelmed by Zigs approach as well. Rust is pretty much the only language making it bearable to me.
- naikrovek 1y agoare you saying that such understanding isn't enough or that every C programmer who said that didn't understand those things? C and Zig aren't the same. I would wager that syntax differences between languages can help you see things in one language that are much harder to see in another. I'm not saying that Zig or C are good or bad for this, or that one is better than the other in terms of the ease of seeing memory problems with your eyes, I'm just saying that I would bet that there's some syntax that could be employed which make memory usage much more clear to the developer, instead of requiring that the developer keep track of these things in their mind. Even if you must manually annotate each function so that some metaprogram that runs at compile time can check that nothing is out of place could help detect memory leaks, I would think. or something; that's just an idea. There's a whole metaprogramming world of possibilities here that Zig allows that C simply doesn't. I think there's a lot of room for tooling like this to detect problems without forcing you to contort yourself into strange shapes simply to make the compiler happy.
- kstenerud 1y ago> are you saying that such understanding isn't enough or that every C programmer who said that didn't understand those things? Probably both. They're words of hubris. C and Zig give the appearance of practicality because they allow you to take shortcuts under the assumption that you know what you're doing, whereas Rust does not; it forces you to confront the edge cases in terms of ownership and provenance and lifetime and even some aspects of concurrency right away, and won't compile until you've handled them all. And it's VERY frustrating when you're first starting because it can feel so needlessly bureaucratic. But then after awhile it clicks: Ownership is HARD. Lifetimes are HARD. And suddenly when going back to C and friends, you find yourself thinking about these things at the design phase rather than at the debugging phase - and write better, safer code because of it. And then when you go back to Rust again, you breathe a sigh of relief because you know that these insidious things are impossible to screw up.
- capitol_ 1y agoJust understanding the rules are not enough, you also need to be consistently good so that you never make a mistake that gets into production. On both your average days and your bad days. Over the 40 to 50 years that your carer lasts. I guess those kind of developers exist, but I know that I'm not one of them.
- zem 1y agothat is the precise point at which the article lost me. ironically it's often good programmers who don't "get" the benefit of building memory management and discipline into the language, rather than leaving it to be a cognitive burden on every programmer.
- pron 1y agoWhat about every Java/JS/Python/Rust/Go programmer who ever created a CVE? Out-of-bounds access is, indeed, a very common cause of dangerous vulnerabilities, but Zig eliminates it to the same extent as Rust. UAF is much lower on the list, to the point that non-memory-safety-related causes easily dominate it.[1] The question is, then, what price in language complexity are you willing to pay to completely avoid the 8th most dangerous cause of vulnerabilities as opposed to reducing them but not eliminating them? Zig makes it easier to find UAF than in C, and not only that, but the danger of UAF exploitability can be reduced even further in the general case rather easily (https://www.cl.cam.ac.uk/~tmj32/papers/docs/ainsworth20-sp.pdf https://www.cl.cam.ac.uk/~tmj32/papers/docs/ainsworth20-sp.p...). So it is certainly true that memory unsafety is a cause of dangerous vulnerabilities, but it is the spatial unsafety that's the dominant factor here, and Zig eliminates that. So if you believe (rightly, IMO) that a language should make sure to reduce common causes of dangerous vulnerabilities (as long as the price is right), then Zig does exactly that! I don't think it's unreasonable to find the cost of Rust justified to eliminate the 8th most dangerous cause of vulnerabilities, but I think it's also not unreasonable to prefer not to pay it. [1]: https://cwe.mitre.org/top25/archive/2024/2024_cwe_top25.html https://cwe.mitre.org/top25/archive/2024/2024_cwe_top25.html
- johncolanduoni 1y agoI don't think the rank on a list that includes stuff like SQL injection and path traversal tells you much about what language features are worthwhile in the C/C++ replacement space. No developer that works on something like Linux or Chromium would introduce a SQL injection vulnerability unless they experienced severe head trauma. They do still introduce use after free vulnerabilities with some regularity.
- pron 1y agoFirst, UAF can be made largely non-dangerous without eliminating it (as in the link above and others). It's harder to exploit to begin with, and can be made much harder still virtually for free. So the number of UAFs and the number of exploitable vulnerabilities due to UAF are not the same, and have to be treated as separate things (because they can be handled separately). Second, I don't care if my bank card details leak because of CSRF or because of a bug in Chromium. Now, to be fair, the list of dangerous vulnerabilities weighs things by number of incidents and not by number of users affected, and it is certainly true that more people use Chrome than those who use a particular website vulnerable to CSRF. But things aren't so simple, there, too. For example, I work on the JVM, which is largely written in C++, and I can guarantee that many more people are affected by non-memory-safety vulnerabilities in Java programs than by memory-safety vulnerabilities in the JVM. Anyway, the point is that the overall danger and incidence of vulnerabilities - and therefore the justified cost in addressing all the different factors involved - is much more complicated than "memory unsafety bad". Yes, it's bad, but different kinds of memory unsafety are bad to different degrees, and the harm can be controlled separately from the cause. Now, I think it's obvious that even Rust fans understand there's a complex cost/benefit game here, because most software today is already written in memory-safe languages, and the very reason someone would want to use a language like Rust in the first place is because they recognise that sometimes the cost of other memory-safe languages isn't worth it, despite the importance of memory safety. If both spatial and temporal safety were always justified at any reasonable cost (that is happily paid by most software already), then there would be no reason for Rust to exist. Once you recognise that, you have to also recognise that what Rust offers must be subject to the same cost/benefit analysis that is used to justify it in the first place. And it shouldn't be surprising that the outcome would be similar: sometimes the cost may be justified, sometimes it may not be.
- johncolanduoni 1y agoYeah, I often wonder if people who have this attitude have ever tried to run a non-trivial C program they wrote with the clang sanitizers on. A humbling experience every time.
- jmull 1y agoI think the problem the practical programmer has with a statement like this is the implication that only certain languages require some basic understanding and a bit of discipline to avoid CVEs. Rust's model has a strict model that effectively prevents certain kinds of logic errors/bugs. So that's good (if you don't mind the price). But it doesn't address all kinds of other logic errors/bugs. It's like closing one door to the barn, but there are six more still wide open. I see rust as an incremental improvement over C, which comes at quite a hefty price. Something like zig is also an incremental improvement over C, which also comes at a price, but it looks like a significantly smaller one. (Anyway, I'm not sure zig is even the right comp for rust. There are various languages that provide memory safety, if that's your priority, which also generally allow dropping into "unsafe" -- typically C -- where performance is needed.)
- estebank 1y ago> But it doesn't address all kinds of other logic errors/bugs. It's like closing one door to the barn, but there are six more still wide open. Could you point at some language features that exist in other languages that Rust doesn't have that help with logic errors? Sum types + exhaustive pattern matching is one of the features that Rust does have that helps a lot to address logic errors. Immutability by default, syntactic salt on using globals, trait bounds, and explicit cloning of `Arc`s are things that also help address or highlight logic bugs. There are some high level bugs that the language doesn't protect you from, but I know of now language that would. Things like path traversal bugs, where passing in `../../secret` let's an attacker access file contents that weren't intended by the developer. The only feature that immediately comes to mind that Rust doesn't have that could help with correctness is constraining existing types, like specifying that an u8 value is only valid between 1 and 100. People are working on that feature under the name "pattern in types".
- jmull 1y agoIMO, simplicity is the number one feature. The developer should spend their attention on the problem space as much as possible, and on the solution space as little as possible. There's a complexity cost to adding features, and while each one may make sense on its own, in aggregate they may collectively burden the developer with too much complexity.
- quotemstr 1y ago> The words of every C programmer who created a CVE. Much of Zig's user base seems to be people new to systems programming. Coming from a managed code background, writing native code feels like being a powerful wizard casting fireball everywhere. After you write a few unsafe programs without anything going obviously wrong, you feel invincible. You start to think the people crowing about memory safety are doing it because they're stupid, or, cowards, or both. You find it easy to allocate and deallocate when needed: "just" use defer, right? Therefore, it someone screws up, that's a personal fault. You're just better, right? You know who used to think that way? Doctors. Ignaz Semmelweis famously discovered that hand-washing before childbirth decreased morality by an order of magnitude. He died poor and locked in an asylum because doctors of the day were too proud to acknowledge the need to adopt safety measures. If mandatory pre-surgical hand-washing step prevented complication, that implied the surgeon had a deficiency in cleanliness and diligence, right? So they demonized Semmelweis and patients continued for decades to die needlessly. I'm sure that if those doctors had been on the internet today, they would say, as the Zig people do say, "skill issue". It takes a lot of maturity to accept that even the most skilled practitioners of an art need safety measures.
- lerno 1y agoI can't speak for Zig users, but an interesting alternative to just new/delete or malloc/free and various garbage collection strategies is pervasive use of temp allocation using arenas, such as Jai and Odin's temp allocators (essentially frame allocators) and C3's stack-like temp allocator. Zig also favours using arenas, but more ad hoc. What happens in those cases is that you drop a whole lot of disorganized dynamic and stack allocations and just handle them in a batch. So in all cases where the problem is tracking temporary objects, there's no need to track ownership and such. It's a complete non-problem. So if you're writing code in domains where the majority of effort to do manual memory management is tracking temporary allocations, then in those cases you can't really meaningfully say that because Rust is safer than a corresponding malloc/free program in C/C++ it's also safer than the C3/Jai/Odin/Zig solution using arenas. And I think a lot of the disagreement comes from this. Rust devs often don't think that switching the use of the allocator matters, so they argue against what's essentially a strawman built from assumed malloc/free based memory patterns that are incorrect. ON THE OTHER HAND, there are cases where this isn't true and you need to do things like safely passing data back and forth between threads. Arenas doesn't help with that at all. So in those cases I think everyone would agree that Rust or Java or Go is much safer. So the difference between domains where the former or the latter dominates needs to be recognised, or there can't possibly be any mutual understanding.