Remix.run Logo
jasonpeacock 3 days ago

> produce memory safe software with a bit of discipline

"a bit of discipline" is doing a lot of work here.

"Just don't write (memory) bugs!" hasn't produced (memory) safe C, and they've been trying for 50yrs. The best practices have been to bolt on analyzers and strict "best practice" standards to enforce what should be part of the language.

You're either writing in Rust, or you're writing in something else + using extra tools to try and achieve the same result as Rust.

fpoling 3 days ago | parent | next [-]

As Rust Zig has type-safe enums/sum types. That alone eliminates a lot of problems with C. Plus sane error handling with good defaults that are better than Rust also contributes to code with less bugs.

Surely there is no borrow checker, but a lot of memory-safety issues with C and C++ comes from lack of good containers with sane interfaces (std::* in C++ is just bad from memory safety point of view).

If C++ gained the proper sum types, error handling and templates in Zig style 15 years ago and not the insanity that is in modern C++ Rust may not exist or be much more niche at this point.

TuxSH 2 days ago | parent | next [-]

> If C++ gained the proper sum types

AFAIK "P2688 R5 Pattern Matching: match Expression" exists and is due C++29 (what actually matters is when it's accepted and implemented by compilers anyway)

Also, cheap bound checks (in Rust) are contingent to Rust's aliasing model.

whatevaa 2 days ago | parent | prev [-]

Buffer overruns are most common memory related RCE's. So bounds checking arrays/strings BY DEFAULT is needed.

tptacek 3 days ago | parent | prev | next [-]

I actively dislike Zig's memory safety story, but this isn't a real argument until you can start showing real vulnerabilities --- not models --- that exploit the gap in rigor between the two languages. Both Zig and Rust are a step function in safety past C; it is not a given that Rust is that from Zig, or that that next step matters in practice the way the one from C does.

dadrian 3 days ago | parent | next [-]

I like Zig, although the Bun Github tracker is full of segfaults in Zig that are presumably quite exploitable. Unclear what to draw from this, though.

[1]: https://github.com/oven-sh/bun/issues?q=is%3Aissue%20state%3...

vanderZwan 3 days ago | parent [-]

Wasn't Bun the project where the creator once tweeted something along the lines of "if you're not willing to work 50+ hours a week don't bother applying to my team"? Because if so then I'm not surprised and also don't think Zig is really to blame for that.

dadrian 3 days ago | parent [-]

Not clear to me there's a correlation between hours worked and number of memory safety vulnerabilities

blacksmith_tb 3 days ago | parent [-]

I think the implication is something like "overwork / fraying morale from long hours means shipping more bugs".

tptacek 3 days ago | parent [-]

The point of memory-safe languages is to foreclose on a set of particularly nasty bugs, regardless of how frayed engineer morale is.

vanderZwan 2 days ago | parent [-]

I'm pretty sure that in an overworked environment the engineers would reach for Rust's unsafe mode pretty quickly because they're too tired to make sense of the borrow checker.

timschmidt 2 days ago | parent | next [-]

I'm no expert, but I've been hacking in Rust for several years now, and the only unsafe I've written was required as part of building a safe interface over some hardware peripherals. Exactly as intended.

The borrow checker is something new Rust devs struggle with for a couple months, as they learn, then the rules are internalized and the code gets written just like any other language. I think new devs only struggle with the borrow checker because everyone has internalized the C memory model for the last 50 years. In another 50, everyone will be unlearning Rust for whatever replaces it.

dadrian 2 days ago | parent | prev [-]

Web browsers and operating systems are full of memory safety bugs, and are not written by engineers in crunch these days.

fuzztester 3 days ago | parent | prev | next [-]

>I actively dislike Zig's memory safety story

Why? Interested to know.

Just for background, I have not tried out either Zig or Rust yet, although I have been interestedly reading about both of them for a while now, on HN and other places, and also in videos, and have read some of the overview and docs of both. But I have a long background in C dev earlier. And I have been checking out C-like languages for a while such as Odin, Hare, C3, etc.

pjmlp 2 days ago | parent | prev [-]

Modula-2 was already a step function in safety past C, but people did not care because it wasn't given away alongside UNIX.

rixed 3 days ago | parent | prev [-]

> "Just don't write (memory) bugs!" hasn't produced (memory) safe C

Yes it did, of course. Maybe it takes years of practice, the assistance of tools (there are many, most very good), but it's always been possible to write memory safe large C programs.

Sure, it's easier to write a robust program in almost every other language. But to state that nobody ever produced a memory safe C program is just wrong. Maybe it was just rethoric for you, but I'm afraid some may read that and think it's a well established fact.

zanellato19 3 days ago | parent [-]

>Yes it did, of course. Maybe it takes years of practice, the assistance of tools (there are many, most very good), but it's always been possible to write memory safe large C programs.

Can you provide examples for it? Because it honestly doesn't seem like it has ever been done.

rixed 2 days ago | parent | next [-]

I don't understand where you stand. Surely, you don't mean that all C programs have memory bugs. But on my side, I'm not claiming that discipline makes C a memory safe language either. This discussion has taken a weird turn.

ramblerman 2 days ago | parent [-]

> you don't mean that all C programs have memory bugs

Well all of them "potentially" do, which is enough from a security standpoint

There have been enough zero days using memory leaks that we know the percentage is also non trivial.

So yes, if programmers can write bugs they will, google SREs were the first to famously measure bugs per release as a metric instead of the old fashioned (and naive) "we aren't gonna write any more bugs"

6P58r3MXJSLi 2 days ago | parent | prev | next [-]

postfix

sqlite

billions of installations and relatively few incidents

zelphirkalt 2 days ago | parent [-]

Few incidents != memory safe

Few incidents != not badly exploitable

Few incidents != no more undiscovered safety bugs/issues

I don't think your examples quite cut it.

dayvster 3 days ago | parent | prev [-]

[flagged]

hannofcart 3 days ago | parent | next [-]

Haven't written C in a while but I think this program has an integer overflow error when you input 2 really large integers such that the sum is more than a 32 bit signed integer.

Also I believe in entering null values will lead to undefined behaviour.

Karrot_Kream 3 days ago | parent | next [-]

Memory safe doesn't mean protection from integer overflow unless you use that integer to index into some array.

I'm not sure how you'd enter NULL given scanf.

Voultapher 3 days ago | parent [-]

I'm not sure how showing that gp can't even write a dozen lines of memory safe C proves that doing so for the exponentially harder 100+k LoC projects is feasible.

The program contains potential use of uninitialized memory UB, because scanf error return is not checked and num1 and num2 are not default initialized. And a + b can invoke signed integer overflow UB. A program with more than zero UB cannot be considered memory safe.

For example if the program runs in a context where stdin can't be read scanf will return error codes and leave the memory uninitialized.

Karrot_Kream 2 days ago | parent [-]

> num1 and num2 are not default initialized

num1 and num2 are declared on the stack and not the heap. The lifetimes of the variables are scoped to the function and so they are initialized. Their actual values are implementation-specific ("undefined behavior") but there is no uninitialized memory.

> And a + b can invoke signed integer overflow UB. A program with more than zero UB cannot be considered memory safe.

No, memory safety is not undefined behavior. In fact Rust also silently allows signed integer overflow.

Remember, the reason memory safety is important is because it allows for untrusted code execution. Importantly here, even if you ignore scanf errors and integer overflow, this program accesses no memory that is not stack local. Now if one of these variables was cast into a pointer and used to index into a non-bounds-checked array then yes that would be memory unsafety. But the bigger code smell there is to cast an index into a pointer without doing any bounds checking.

That's sort of what storing indexes separately from references in a lot of Rust structures is doing inadvertently. It's validating accesses into a structure.

Voultapher 2 days ago | parent [-]

Regarding initialization, if one wants portable code that works for more than one machine+compiler version, it's advisable to program against the C++ virtual machine specified in the standard. This virtual machine does not contain a stack or heap.

Generally your comment strikes me as assuming that UB is some kind of error. In practice UB is more a promise the programmer made to never do certain things, allowing the compiler to assume that these things never happen.

How UB manifests is undefined. A program that has more than zero UB cannot be assumed to be memory safe because we can't make any general assumptions about its behavior because. UB is not specified to be localized it can manifest in any way, rendering all assumptions about the program moot. In practice when focusing on specific compilers and machines we can make reasonable localized assumptions, but these are always subject to change with every new compiler version.

Memory safety is certainly critical when it comes to exploits, but even in a setting without adversaries it's absolutely crucial for reliability and portability.

> In fact Rust also silently allows signed integer overflow.

Silently for release builds, and panic in debug builds. The behavior is implementation defined and not undefined, in practice this is a subtle but crucial difference.

Take this example https://cpp.godbolt.org/z/58hnsM3Ge the only kind of UB AFAIKT is signed integer overflow, and yet we get an out-of-bounds access. If instead the behavior was implementation defined the check for overflow would not have been elided.

dayvster 3 days ago | parent | prev [-]

har har... have my upvote!

zanellato19 3 days ago | parent | prev [-]

I wasn't trying to be a dick, I am saying that my experience is that no big C program is ever safe. You replied that it is possible and I asked for an example. Providing a small script to prove that big C programs are safe isn't enough.

dayvster 3 days ago | parent [-]

Making a broad statement like there has never been a memory safe C program is a bit of a dickish thing to say.

especially when you phrase it as

> Can you provide examples for it? Because it honestly doesn't seem like it has ever been done.

it comes off as pedantic and arrogant.

It obviously is possible to write memory safe software in C and obviously it has been done before otherwise we would not be currently communicating over the goddamn internet.

Asking for evidence of something this obvious is akin to asking for a source on if water is in fact wet.

zanellato19 3 days ago | parent | next [-]

I think pretty much any non trivial C example has memory safety issues. It doesn't mean that they aren't useful and can't be used. But time and time again we have seen security reports that point to memory issues. So no, I don't think I'm asking for something obvious, quite the contrary. I think the claim that it's possible to write big C programs that are memory safe is really strong and I heavily disagree with it.

zelphirkalt 2 days ago | parent | prev | next [-]

It's not dickish, and it's weird you seem to feel attacked/offended by that. It is a realistic conclusion, that we have come to over the course of decades of C usage. One could call it wisdom or collective learning.

ksec 3 days ago | parent | prev [-]

>> Can you provide examples for it? Because it honestly doesn't seem like it has ever been done.

>it comes off as pedantic and arrogant.

Interesting the way this was perceived. I thought he was just asking a honest question.

Again shows online discussion and communication is hard.