Live data from Hacker News

Memory safety is necessary, not sufficient

steveklabnik.com

61–70 of 162 posts

Re: Memory safety is necessary, not sufficient

#61
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…

> But in the main, data races have not empirically proved out as a source of exploited vulnerabilities. Say what? Data races, otherwise lumped under the bucket “timing attacks”, are a common source of security exploits. A basic example is racing with code that is creating a file and applying an ACL in two steps. If I can “time” things right from a concurrent thread/process, I can get into this file before the ACL pre…

Isn't it rather trivial to prevent this by creating a file with a random filename, applying the ACL, then renaming the file to the correct name?

Re: Memory safety is necessary, not sufficient

#62
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…

To me it’s a deep philosophical post in the vein of “what even is memory safety anyway?”

> The piece makes the case that Python isn't memory safe

It’s a philosophy argument tactic. Take something everyone considers to be true “Python is memory safe” then push it to logical extremes. The purpose of this isn’t to learn anything about Python, the purpose is to learn about the extremes. In this case about memory safety.

I think the overall point is that “memory safe languages don’t truly exist” in the purist sense, since every lang must touch unsafe code at some point. However some languages and tools do a better job is isolating these interactions. We call these tools “memory safe”.

Re: Memory safety is necessary, not sufficient

#63
post #37
post #27

Earlier quoted context omitted.

uh. No. Rust unsafe gives rust behavior a lot like C. If you at all break the rather subtle rules, then essentially anything can and will happen. So for example, there was recently a thread where someone had code that checked if a value was in range to safely coerce it directly to an enum then did so. But because of eager evaluation of an argument the unsafe cast happened first. From this the compiler reasoned that t…

> If you at all break the rather subtle rules, then essentially anything can and will happen. If by subtle rules you mean your invariants, that is missing fundamental assumptions. It's akin to making a building without foundation and load bearing structures. > So for example, there was recently a thread where someone had code that checked if a value was in range to safely coerce it directly to an enum then did so. Bu…

> Issue it had was safe code was invalidating the invariants unsafe code was relying on. Iirc alignment.

You do recall correctly. The safe code was producing a pointer with alignment that was off, and the unsafe code dereferenced it without checking. I felt that it was kind of a bad take when several people said that it was UB caused by safe code, because really the issue was that the unsafe code wasn't doing its job. The Rust unsafe model is that you can't trust safe code when inside unsafe code. It's on the unsafe code to uphold invariants which it requires, not the safe code which calls it

Re: Memory safety is necessary, not sufficient

#64

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's not like PL/I didn't allow for similar flaws, so "Worse is better" is neither here nor there. At least C was simple enough to learn for most programmers. It's still generally the case that a simple approach is more likely to be correct than an overly complicated one for which it's not even clear what "correct" means.

> It's not like PL/I didn't allow for similar flaws, so "Worse is better" is neither here nor there.

PL/I is one of the reasons that Multics was not plagued by buffer overflows:

"The net result is that a PL/I programmer would have to work very hard to program a buffer overflow error, while a C programmer has to work very hard to avoid programming a buffer overflow error." [1]

[1] P. Karger, R. Schell, "Thirty Years Later: Lessons from the Multics Security Evaluation"

Re: Memory safety is necessary, not sufficient

#65
post #40
post #37

Earlier quoted context omitted.

> If you at all break the rather subtle rules, then essentially anything can and will happen. If by subtle rules you mean your invariants, that is missing fundamental assumptions. It's akin to making a building without foundation and load bearing structures. > So for example, there was recently a thread where someone had code that checked if a value was in range to safely coerce it directly to an enum then did so. Bu…

> If by subtle rules you mean your invariants, that is missing fundamental assumptions. > It's akin to making a building without foundation and load bearing structures. That's exactly how C approaches UB too. > However note the UB goes away if you never use any unsafe code. Or if you expand your unsafe to encompas some safe code. Right. The problem is that's untenable; any nontrivial program will have unsafe somewher…

Particularly notable: due to the restrictions that Rust chooses to enforce on safe code, `unsafe` is forced in a lot of situations where other languages maintain full runtime safety. I'm not saying going full-Java is the only answer, but a language that is safer than Rust is certainly possible.

Re: Memory safety is necessary, not sufficient

#66
post #45
post #41

Earlier quoted context omitted.

> I have a hard time not reading them as shibboleths for "Rust is the only safe language", which is manifestly false. Given that quite simple classes of vulnerabilities are endemic to all other major languages, no, it's not "manifestly false". The state of software safety really is bad enough that "all major languages that aren't Rust are unsafe" is plausible. > The vulnerabilities endemic to memory-safe languages (l…

Given that quite simple classes of vulnerabilities are endemic to all other major languages, no, it's not "manifestly false". The state of software safety really is bad enough that "all major languages that aren't Rust are unsafe" is plausible. We're really very good at documenting vulnerabilities; the mere documentation of vulnerabilities is itself a 9-figure industry. So: cough up the examples. I can't think of any…

> We're really very good at documenting vulnerabilities; the mere documentation of vulnerabilities is itself a 9-figure industry. So: cough up the examples. I can't think of any, so that's where I'm setting the bar for you.

Your own post listed a bunch of vulnerability classes that happen in those languages ("logic and higher-level vulnerabilities like SQLI, metacharacter quoting, filesystem traversal, and cryptography bugs").

Re: Memory safety is necessary, not sufficient

#67
post #40

Earlier quoted context omitted.

> If by subtle rules you mean your invariants, that is missing fundamental assumptions. > It's akin to making a building without foundation and load bearing structures. That's exactly how C approaches UB too. > However note the UB goes away if you never use any unsafe code. Or if you expand your unsafe to encompas some safe code. Right. The problem is that's untenable; any nontrivial program will have unsafe somewher…

> If Rust doesn't give you more and better support in doing that than C does, then it's not really making a difference. It does and if you've been missing that you've misunderstood this whole discussion. Rust allows you to wrap up some unsafe code in a safe abstraction. You use the type checker to enforce your invariants, such that the unsafe code can be reviewed in isolation. Rust gives you exactly what you're sayin…

> It does and if you've been missing that you've misunderstood this whole discussion.

Don't tell it to me, tell it to the person I was replying to.

Re: Memory safety is necessary, not sufficient

#68
post #44
post #40

Earlier quoted context omitted.

> If by subtle rules you mean your invariants, that is missing fundamental assumptions. > It's akin to making a building without foundation and load bearing structures. That's exactly how C approaches UB too. > However note the UB goes away if you never use any unsafe code. Or if you expand your unsafe to encompas some safe code. Right. The problem is that's untenable; any nontrivial program will have unsafe somewher…

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.)

Re: Memory safety is necessary, not sufficient

#69
post #40
post #37

Earlier quoted context omitted.

> If you at all break the rather subtle rules, then essentially anything can and will happen. If by subtle rules you mean your invariants, that is missing fundamental assumptions. It's akin to making a building without foundation and load bearing structures. > So for example, there was recently a thread where someone had code that checked if a value was in range to safely coerce it directly to an enum then did so. Bu…

> If by subtle rules you mean your invariants, that is missing fundamental assumptions. > It's akin to making a building without foundation and load bearing structures. That's exactly how C approaches UB too. > However note the UB goes away if you never use any unsafe code. Or if you expand your unsafe to encompas some safe code. Right. The problem is that's untenable; any nontrivial program will have unsafe somewher…

The problem is that's untenable; any nontrivial program will have unsafe somewhere

I'm up to 47,000 lines of Rust with no "unsafe". The main program starts with

#![forbid(unsafe_code)]

and that applies to the entire program, although not external crates. If you're not using foreign functions, you don't need "unsafe".

Some published crates I use do have "unsafe", more than they should. This is annoying.

Re: Memory safety is necessary, not sufficient

#70
post #66
post #45

Earlier quoted context omitted.

Given that quite simple classes of vulnerabilities are endemic to all other major languages, no, it's not "manifestly false". The state of software safety really is bad enough that "all major languages that aren't Rust are unsafe" is plausible. We're really very good at documenting vulnerabilities; the mere documentation of vulnerabilities is itself a 9-figure industry. So: cough up the examples. I can't think of any…

> We're really very good at documenting vulnerabilities; the mere documentation of vulnerabilities is itself a 9-figure industry. So: cough up the examples. I can't think of any, so that's where I'm setting the bar for you. Your own post listed a bunch of vulnerability classes that happen in those languages ("logic and higher-level vulnerabilities like SQLI, metacharacter quoting, filesystem traversal, and cryptograp…

He says explicitly that these are endemic to memory-safe languages, including Rust. They aren't something that Rust handles better than Python or Java.
Post reply on HN