Live data from Hacker News

Redox OS Crash Challenge

github.com

51–60 of 82 posts

Re: Redox OS Crash Challenge

#51

Earlier quoted context omitted.

> like forgetting to check error returns One of the most common bugs in C (in my experience) is forgetting to check the error return on a malloc call. Kind of the worst of both worlds.

Using exceptions solves that problem and many others besides; it's a shame they're not currently in fashion. But you do end up needing them, so in Rust, we end up with error codes _and_ exceptions (but spelled "panic").

I wouldn't call panic the same thing as exceptions - panics are quite explicitly meant to not be caught, except at fairly hefty boundaries like processes, threads, or FFI. Using std::panic::catch_unwind to catch, say, accessing an out-of-bounds element in a vector would be super un-idiomatic, both because that's what .get() -> Option is for, and also because even if you catch the panic, the message gets printed to stderr: https://play.rust-lang.org/?gist=587f976dc4bcf4010eb0026c9ed...

Rust doesn't have exceptions in the sense that C++/Java/Python/etc. have exceptions, i.e., things that unwind the stack and are part of a function's expected API. And I think the specific reason they're out of style is the inherent contradiction in that statement: either all the exceptions in the API of any of the functions you call are also part of your public API, or you're carefully filtering exceptions in any of the functions you call that raise them, and so you might as well not use unwinding.

Panics unwind the stack, but are not part of the API; they're for erroneous conditions where the usual right thing to do is to kill the process, but maybe you only want to kill e.g. the current HTTP request. Errors as return values / the Result type do not automatically unwind - they're just normal data types returned from a function - but they have syntax (the question mark operator) for explicitly unwinding them one step, and there are proposals in progress to introduce syntax that use "throw" or "catch" to refer to returning the error case or handling such returns in a block of code, so it seems like people think Result more closely matches exceptions in other languages.

Re: Redox OS Crash Challenge

#52
post #25

Earlier quoted context omitted.

> There are plenty of security/safety bugs that aren't about dereferencing a null or accessing invalid ptr. Sure, but there are also plenty of improvements in Rust that aren't about memory safety. For instance, there's the improved type system over C or C++ (tuples, enums, traits, etc.), related features like pattern-matching on enums and trait-based error handling (the question-mark operator), and a macro system tha…

> like forgetting to check error returns One of the most common bugs in C (in my experience) is forgetting to check the error return on a malloc call. Kind of the worst of both worlds.

> One of the most common bugs in C (in my experience) is forgetting to check the error return on a malloc call.

Very unlikely.

1. it won't happen in regular use, only if your are asking for a huge amount of memory (possibly by mistake), or the system is already full and you will likely experience problems with the whole system (freezes, instability, processes killed, etc) and not just with your program.

2. it will never happen in Linux, because in the classical setup, malloc() never returns NULL, even when there is no memory available.

So you have to have those conditions + a return value unchecked for the bug to have a chance to appear. There are thousands of other bug sources.

Re: Redox OS Crash Challenge

#53

Earlier quoted context omitted.

Rust is significantly different with regards to this stuff: * There is no reflection API * Exceptions don't exist * There's no subtyping, so ClassCastExceptions can't exist. (There's subtyping with lifetimes, and you can't cast them, so that doesn't count) * final doens't exist That said, every language has things that you don't realize; we did have a sort of similar moment to this stuff before 1.0 with the "leakapoc…

> Exceptions don't exist They're called panics. > There's no subtyping, so ClassCastExceptions can't exist. Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem. > final doens't exist Sure it does. It's just implied, and not-final has to be spel…

> Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem.

Can you explain this? Do you mean that the type C does not correctly implement A? Do you mean something that expects a specific value from a methid in A that only B will return? Both of those, while possible just seem like a complaint of "X doesn't prevent me from purposely breaking it".

Re: Redox OS Crash Challenge

#54

Earlier quoted context omitted.

> Exceptions don't exist They're called panics. > There's no subtyping, so ClassCastExceptions can't exist. Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem. > final doens't exist Sure it does. It's just implied, and not-final has to be spel…

> Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem. Can you explain this? Do you mean that the type C does not correctly implement A? Do you mean something that expects a specific value from a methid in A that only B will return? Both of tho…

One example is something like enum A { B, C }: a function might have a precondition that it requires an A::B, and crashes/misbehaves when given an A::C. In Rust, this can be seen in Option::unwrap (requires a Some, panicking if given a None). Technically this is the same sort of thing as in Java, but, at least to me, it seems different/more easily controlled.

Re: Redox OS Crash Challenge

#55
post #30

Earlier quoted context omitted.

The official rust book [1] is a great place to start. So are the exercism tutorials [2] [1] https://doc.rust-lang.org/book/ [2] http://exercism.io/languages/rust/about

Version 1 or 2 of the rust book?

Author here. 2 is much better. And it’s almost done; we’re mostly in editing and bikeshedding the opening paragraph.

Re: Redox OS Crash Challenge

#56

Earlier quoted context omitted.

To my mind Rust is neither a panacea nor a mere mitigation strategy. It (or another language like it) is a necessary condition for anything like generally safe (not perfect) computing. Please don't jump to the conclusion that someone who thinks that Rust isn't just one more mitigation strategy is an addled fanboi who thinks it's a total panacea and snake oil. That is NOT what they're saying. They are saying it's nece…

The idea that something can be "necessary but not sufficient" comes up a lot, and is very often misunderstood. Rust-like guarantees are necessary but not sufficient for safe systems.

As DJB and other excellent programmers have demonstrated, they're not strictly necessary either.

(and I really like Rust)

Re: Redox OS Crash Challenge

#57
post #32

Earlier quoted context omitted.

Capability-safe languages in the E family, like E and Monte, have perfect isolation, or as it's known in the community, "working encapsulation." In a capability-safe system, only bugs in the implementation, such as runtime or CPU bugs, can violate isolation. Here's an introduction to E: http://www.erights.org/talks/promises/paper/tgc05-submitted.... The Monte language's manual starts with a tutorial and an explanatio…

That's all nice but what if you have a CPU bug like Spectre? Isolation is nice in userspace but in kernelspace the rules are somewhat different, especially considering that it is the task of kernelspace to mediate and abstract hardware access to arbitrary programs running on your system. Any number of hardware bugs may break isolation. Any number of wrong assumption or subtle logic bugs can happen and break the isola…

"That's all nice but what if you have a CPU bug like Spectre?"

Use VAMP [1] or AAMP7G [2] with techniques [3] that prevent leaks if you're worried about that. Far as RAM/Rowhammer, either use techniques that trust it less like Edmison's [4] or actually do QA when you build your own. A RAM engineer told me they were intentionally under-designed for cost-cutting and/or rushing to market. There's also an open, cell library available. Then, you get some analog and RF engineers that don't trust each other to look at the rest of the mixed-signal chip. You should be good on what requirements you've stated so far. If worried about kernel security, modify that same chip to use CHERI [5] which already runs FreeBSD but you'll want a separation kernel. Throw in asynchronous or masked execution for timing channel mitigation.

I still agree you want containment, detection, and recovery mechanisms just in case where you can put them in. Mainly in case of hardware failures but also unknown attack classes.

[1] http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.217...

[2] http://www.ccs.neu.edu/home/pete/acl206/slides/hardin.pdf

[3] https://pastebin.com/ajqxDJ3J

[4] https://vtechworks.lib.vt.edu/bitstream/handle/10919/29244/e...

[5] http://www.cl.cam.ac.uk/research/security/ctsrd/cheri/

Re: Redox OS Crash Challenge

#58

Earlier quoted context omitted.

Rust is significantly different with regards to this stuff: * There is no reflection API * Exceptions don't exist * There's no subtyping, so ClassCastExceptions can't exist. (There's subtyping with lifetimes, and you can't cast them, so that doesn't count) * final doens't exist That said, every language has things that you don't realize; we did have a sort of similar moment to this stuff before 1.0 with the "leakapoc…

> Exceptions don't exist They're called panics. > There's no subtyping, so ClassCastExceptions can't exist. Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem. > final doens't exist Sure it does. It's just implied, and not-final has to be spel…

See above about panics and exceptions; just because they’re similar doesn’t mean they’re the same.

I agree Rust doesn’t solve all bugs.

Re: Redox OS Crash Challenge

#60
post #54

Earlier quoted context omitted.

> Any sort of polymorphism opens you up to the possibility that code that's written to take abstract type A, implemented concretely in B and C, implicitly expects a B and blows up when it gets a C. Rust doesn't solve this problem. Can you explain this? Do you mean that the type C does not correctly implement A? Do you mean something that expects a specific value from a methid in A that only B will return? Both of tho…

One example is something like enum A { B, C }: a function might have a precondition that it requires an A::B, and crashes/misbehaves when given an A::C. In Rust, this can be seen in Option::unwrap (requires a Some, panicking if given a None). Technically this is the same sort of thing as in Java, but, at least to me, it seems different/more easily controlled.

Unwrap is essentially asking for it to fail under that condition, so that's not exactly broken.

Unwrap should always be suspect. It's easy to turn it into a pattern matcher instead, which explicitly forces you to hand the none case.

I'm not saying you're wrong, but I don't think it's an example of an error created by a polymorphic type. (Instances of the same type can do this as well.)

Post reply on HN