Live data from Hacker News

Memory safety is necessary, not sufficient

steveklabnik.com

141–150 of 162 posts

Re: Memory safety is necessary, not sufficient

#141
post #65
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…

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.

Like what exactly?

Re: Memory safety is necessary, not sufficient

#142
post #106
post #48

Earlier quoted context omitted.

It's deprecated for removal.[0] [0] https://openjdk.org/jeps/411

GraalVM has Isolates that can do this on a much more fine-grained level and with multiple languages (it can also run LLVM-languages now).

I'd seen that https://www.graalvm.org/latest/security-guide/polyglot-sandb... is JavaScript-only at this point, I guess it must build on https://www.graalvm.org/latest/reference-manual/embed-langua... and one could roll their own for any language?

Is there a good example, doc, or is it even a thing, to use GraalVM Isolates to defend against Java supply chain attacks, nevermind other languages? I guess it might be possible, going by a comment on another thread https://news.ycombinator.com/item?id=38278131 but require careful construction of anything you'd want to have only the capabilities you pass to it?

(Naive questions, apologies, I should really learn by trying it out instead!)

Re: Memory safety is necessary, not sufficient

#143

Earlier quoted context omitted.

Software was significantly simpler in those days. I don't find it strange that they took a simplified view of software engineering. Specifically because those exact same simplified views still exist today - talk to people who've never worked on large complex systems, and you will usually encounter similar "anti-perfectionism". People adopt simplified engineering practices when working on simple software by themselves…

One of the reasons C became popular because the compiler was actually reasonable to use on the hardware of the time.

Yeah it's hard for a lot of programmers to context switch back to when a megabyte a HUGE amount of memory (or even 640kB). I think everyone should play around on arduino uno or even smaller memory cpus to get some perspective. You didn't have gigabytes of rams to analyze all corner cases, data races, etc. during compilations.

Re: Memory safety is necessary, not sufficient

#144
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.

Object-capability models really shine there: https://en.m.wikipedia.org/wiki/Object-capability_model What if the only way to access the file system was to call methods on an object that was provided to main()? Then libraries would only be able to access the file system if they got a reference to that object.

The OP does mention Austal as one of a few languages putting their own twist on Rust learnings, though the most interesting thing to me about Austral is indeed https://borretti.me/article/how-capabilities-work-austral rather than simply memory safety (though that's essential too).

Re: Memory safety is necessary, not sufficient

#145
post #118

Earlier quoted context omitted.

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

> The key thing to understand is that if you use these flags, you opt-in to a non-standard C dialect. Isn't all C with undefined behavior non-standard. Or is there a standard for undefined behavior (obviously not, I would think)? I don't understand why those flags wouldn't be turned on by default. Or do they affect more than just undefined behavior?

They affect performance, forcing the dev to insure they aren't doing unsafe/ill-defined things which is almost impossible on huge code bases in c/c++

Re: Memory safety is necessary, not sufficient

#146
post #106

Earlier quoted context omitted.

GraalVM has Isolates that can do this on a much more fine-grained level and with multiple languages (it can also run LLVM-languages now).

I'd seen that https://www.graalvm.org/latest/security-guide/polyglot-sandb... is JavaScript-only at this point, I guess it must build on https://www.graalvm.org/latest/reference-manual/embed-langua... and one could roll their own for any language? Is there a good example, doc, or is it even a thing, to use GraalVM Isolates to defend against Java supply chain attacks, nevermind other languages? I guess it might be pos…

I believe it should work with any other Graal language (currently, JS, Python are the bigger ones and Sulong can run LLVM bytecode. There is also Espresso, which runs “java on top of java”, making it also eligible for these security boundaries).

I don’t think it is too commonly used yet, but yeah, it can even do stuff like limit CPU usage within an isolate, so it should be more than possible to limit the scope of such an attack.

Re: Memory safety is necessary, not sufficient

#147
post #118
post #74

Earlier quoted context omitted.

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

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

>The key thing to understand is that if you use these flags, you opt-in to a non-standard C dialect.

This is not true. The C Standard explicitly states that a conforming implementation is welcome to provide well defined semantics to behavior that the standard states is undefined.

The whole point of undefined behavior is that the C Standard imposes no requirement on implementations about the semantics of that program, so if a specific implementation adds some kind of checks or provides some sort of deterministic behavior to something that is otherwise undefined, the program itself is still C code and adheres to the C Standard.

>Your code can no longer be compiled by a compiler that does not support these special C dialects.

Undefined behavior is a semantic property of a program, not a syntactic property, so any other conforming C compiler will have no problem compiling it.

Re: Memory safety is necessary, not sufficient

#148

Earlier quoted context omitted.

> The key thing to understand is that if you use these flags, you opt-in to a non-standard C dialect. Isn't all C with undefined behavior non-standard. Or is there a standard for undefined behavior (obviously not, I would think)? I don't understand why those flags wouldn't be turned on by default. Or do they affect more than just undefined behavior?

They affect performance, forcing the dev to insure they aren't doing unsafe/ill-defined things which is almost impossible on huge code bases in c/c++

They are unhappy being forced to write code that is free of undefined behavior?

It reminds me of the joke: Alice claims she is very fast at mental math. Bob asks "what's 4821 times 5997?" Alice replies "ten thousand." Bob says, "What, no, that's wrong, very wrong." Alice says, "But it was fast!"

Are you telling me C / C++ developers are like Alice? When given the choice between fast undefined behavior and slower but more likely to be correct undefined behavior, developers will choose the faster option that is more likely to be incorrect?

Re: Memory safety is necessary, not sufficient

#149
post #66

Earlier quoted context omitted.

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

Even if that's true (and I have my doubts), it doesn't make those non-Rust languages safe.

Re: Memory safety is necessary, not sufficient

#150
post #38

Earlier quoted context omitted.

> They don't have "you can use it only within this scope" (they may use a closure/callback to give access to an unsafe object, but these aren't hermetic, so that's a convention not a guarantee). You can use the same trick as Haskell's STRef to prevent reusing a "leaked" unsafe object, although it's cumbersome enough in Java that you may not want to.

The ST monad trick requires second-order polymorphism, though [to type runST :: forall a. (forall s. ST s a) -> a]. Are any of those languages capable of it?

Java certainly is; you might have to encode it as having your callback be an object with a (polymorphic) method, but for a long time that was something you had to do to express any callback in Java, so it's well-supported.
Post reply on HN