Live data from Hacker News

Memory safety is necessary, not sufficient

steveklabnik.com

71–80 of 162 posts

Re: Memory safety is necessary, not sufficient

#71
post #5

I don't think the government's goal in improving memory safety is because of Rust or any other particular technology. The government buys technology from wherever, and until recently they never really cared where they got it from. If they need a USB Emulator, they buy the same Chinese Gotek from Ebay that you or I buy, and they get the same "Driver CD" full of buggy, broken English software, written by one person for…

Just like in every other kind of engineering, for software capability pulls the requirements. The only reason everybody is complaining about lack of memory safety now is because there are alternatives for every use case. Before Rust existed, it was seen as an inevitable issue that one must work with, not as a problem to solve.

>Before Rust existed, it was seen as an inevitable issue that one must work with, not as a problem to solve.

There were many memory safe languages before Rust, Java and C# evangelized this a lot, though at that time the accent was on memory leaks not on safety. Rust offers an alternative for low level programming and might be faster in soem scenarios then managed languages.

Re: Memory safety is necessary, not sufficient

#72
post #44

Earlier quoted context omitted.

Exactly. All-hope-lost behavior is possible in rust code unless there is no unsafe anywhere (and no compiler bugs, but I think its fair to ignore those when discussing the language in the abstract). Rust potentially benefits from fewer opportunities to footgun yourself, but rust also comes with other costs (including a more complex syntax, a bad dependency culture, a lot more front-loaded cognitive load around lifeti…

> compiler bugs... its fair to ignore those when discussing the language in the abstract When the language is defined as whatever the compiler does , as it is in the case of Rust, I'm not so sure. If there were a Rust standard with multiple compliant compilers, I'd be more convinced, but Rust isn't there yet. (And TRF's trademark policy may well prevent it from ever getting there.)

Having more implementations doesn’t really help you avoid bugs in the one you’re using.

Re: Memory safety is necessary, not sufficient

#73
post #35

I'm not sure I understand what this piece is trying to say about Python memory safety. Conventionally, in software security, Python is considered a memory-safe language. The piece makes the case that Python isn't memory safe when you FFI into a C library. But neither is Rust, nor is it when you use `unsafe`. What matters in both case is how little unsafe code you end up writing. Memory safety is a software security c…

Data races are definitely exploited! If we are considering TOCTOU issues then this is a very easy way to get fairly reliable and simple exploits. If we are talking about races of the “two threads access the same value” kind then it’s easy (well, assuming reliability is an exercise for the reader) to turn this into a UAF or OOB access by having one thread work with a stale version of an object that has been modified elsewhere.

Re: Memory safety is necessary, not sufficient

#74

I think it’s worth emphasizing that the C spec’s love of undefined behavior—if you do X by accident, anything can happen—and the apparently massive amount of memory-unsafe software that has been written that will just allocate 16 bytes on the stack and then read from a file descriptor until it encounters a null byte… are examples of things that aren’t considered remotely sane or reasonable to a modern programmer or l…

>it is more important that the implementation—or the design of the implementation—of a piece of software be simple than that it be correct.

This is true and when your compiler actually abides by these values it is shocking how many issues just go away. The problem is that gcc and clang are nowhere near a simple implementation, asking the question of how exactly gcc or clang arrived at some given assembly for some given input is a really complicated answer. So much so that it makes me say that the relationship between the programmer and the compiler becomes adversarial. It would be one thing to just have very complicated optimizations but the whole "undefined behavior lets us to anything" approach is what makes it unbearable.

People can (and do) point at the C spec for fault of this and it is true that if the C spec was more strict then these compilers would not have the free pass to do these crazy miscompilations. However there is nothing stopping these compilers from just not doing that, there is nothing stopping them from just defining their own sane behavior for what the C spec defines as undefined behavior. It is no longer the case where we have a dozen or so C compilers that people need to target with their programs, the spec is not the bottom line anymore.

The Plan 9 compilers are the perfect example of getting this right. They define sane behavior that a reasonable programmer would expect for what the C spec calls undefined behavior. They are not gargantuan, their optimizations are not crazy. It is generally easy to understand how the compiler ended up with the assembly you see in the binary. Yet they are competent enough to selfhost an entire OS. The insane complexity of these other C compilers is simply not mandatory. They are not perfect of course it is still possible to write bad code but the result is no longer pathological, which is a giant help when you're actually trying to figure out what is going wrong.

Re: Memory safety is necessary, not sufficient

#75
post #22

Our programs are growing so big by having so many (indirect) dependencies that we need a way to sandbox the libraries that we include from our main programs. This is the type of safety that I'm looking for, really.

Address spaces are typically difficult to mix things in, unfortunately. If you sandbox harder then it’s not actually very useful to have them in your process anymore.

Re: Memory safety is necessary, not sufficient

#76

I think it’s worth emphasizing that the C spec’s love of undefined behavior—if you do X by accident, anything can happen—and the apparently massive amount of memory-unsafe software that has been written that will just allocate 16 bytes on the stack and then read from a file descriptor until it encounters a null byte… are examples of things that aren’t considered remotely sane or reasonable to a modern programmer or l…

Undefined behavior is critical for performance. Without undefined behavior, C compilers would not be able to optimize at all. You'd be running everything at -O0 or worse.

Re: Memory safety is necessary, not sufficient

#77
post #35

I'm not sure I understand what this piece is trying to say about Python memory safety. Conventionally, in software security, Python is considered a memory-safe language. The piece makes the case that Python isn't memory safe when you FFI into a C library. But neither is Rust, nor is it when you use `unsafe`. What matters in both case is how little unsafe code you end up writing. Memory safety is a software security c…

While data races may not be a top category empirically, they are undefined behavior, which means that (a future version of) the compiler is allowed to make your program do anything at all after a data race happens. We are setting the bar incredibly low for ourselves if we just accept that things like that happen on the regular.

Re: Memory safety is necessary, not sufficient

#78

Earlier quoted context omitted.

> compiler bugs... its fair to ignore those when discussing the language in the abstract When the language is defined as whatever the compiler does , as it is in the case of Rust, I'm not so sure. If there were a Rust standard with multiple compliant compilers, I'd be more convinced, but Rust isn't there yet. (And TRF's trademark policy may well prevent it from ever getting there.)

Having more implementations doesn’t really help you avoid bugs in the one you’re using.

[deleted]

Re: Memory safety is necessary, not sufficient

#79
post #35

I'm not sure I understand what this piece is trying to say about Python memory safety. Conventionally, in software security, Python is considered a memory-safe language. The piece makes the case that Python isn't memory safe when you FFI into a C library. But neither is Rust, nor is it when you use `unsafe`. What matters in both case is how little unsafe code you end up writing. Memory safety is a software security c…

> Conventionally, in software security, Python is considered a memory-safe language. The piece makes the case that Python isn't memory safe when you FFI into a C library.

Interesting and largely unknown trivia: it's possible to invoke memory errors in the underlying C interpreter from pure Python code — no libraries and no imports needed!

One way of doing this is by creating new `code` objects with crafted bytecode. There is no bytecode verifier in Python to make sure, say, referenced stack variables in the VM are valid...

Re: Memory safety is necessary, not sufficient

#80
post #74

I think it’s worth emphasizing that the C spec’s love of undefined behavior—if you do X by accident, anything can happen—and the apparently massive amount of memory-unsafe software that has been written that will just allocate 16 bytes on the stack and then read from a file descriptor until it encounters a null byte… are examples of things that aren’t considered remotely sane or reasonable to a modern programmer or l…

>it is more important that the implementation—or the design of the implementation—of a piece of software be simple than that it be correct. This is true and when your compiler actually abides by these values it is shocking how many issues just go away. The problem is that gcc and clang are nowhere near a simple implementation, asking the question of how exactly gcc or clang arrived at some given assembly for some giv…

How do the Plan 9 compilers compare to gcc/clang when it comes to performance or portability?
Post reply on HN